首页 > Web开发 > 详细

[题解] [JSOI2014] 歌剧表演

时间:2020-02-11 21:41:31      阅读:61      评论:0      收藏:0      [点我收藏+]

题面

题解

我们可以把这些人拆成一些集合, 保证对于一个集合你只知道这个整体, 而无法分辨出哪一部分是哪些人

起初所有人都在一个集合中

我们对于每一次操作, 肯定会有一些人属于同一个集合

那你就可以从这个集合中分辨出这些人来, 把这些人抠出来重新丢进一个集合

最后一个人一个集合的就可以被分辨出来

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <set>
const int N = 100005; 
using namespace std;

int n, m, id[N], a[N], ans[N], cnt = 1;
set<int> s[N]; 

template < typename T >
inline T read()
{
    T x = 0, w = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * w; 
}

bool cmp(int a, int b) { return id[a] < id[b]; }

int main()
{
    n = read <int> (), m = read <int> ();
    for(int i = 1; i <= n; i++) s[id[i] = 1].insert(i); 
    int num, last; 
    for(int t = 1; t <= m; t++)
    {
    num = read <int> ();
    for(int i = 1; i <= num; i++) a[i] = read <int> ();
    sort(a + 1, a + num + 1, cmp), a[num + 1] = 0;
    last = 1;
    for(int i = 2; i <= num + 1; i++)
        if(id[a[i]] != id[a[i - 1]])
        {
        for(int j = last; j < i; j++) s[id[a[j]]].erase(a[j]);
        ++cnt; 
        if(s[id[a[last]]].size() == 1 && !ans[*s[id[a[last]]].begin()])
            ans[*s[id[a[last]]].begin()] = t; 
        if(last == i - 1 && !ans[a[last]])
            ans[a[last]] = t;
        for(int j = last; j < i; j++) s[id[a[j]] = cnt].insert(a[j]);
        last = i; 
        }
    }
    for(int i = 1; i <= n; i++) printf("%d%c", ans[i], i == n ? '\n' : ' '); 
    return 0; 
}

[题解] [JSOI2014] 歌剧表演

原文:https://www.cnblogs.com/ztlztl/p/12296674.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!