zoukankan      html  css  js  c++  java
  • [题解] [JSOI2014] 歌剧表演

    题面

    题解

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

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

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

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

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

    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 ? '
    ' : ' '); 
        return 0; 
    }
    
  • 相关阅读:
    计算机专业找工作注意什么
    LU分解
    HDU2050
    牛牛与字符串border 题解(gcd)
    牛牛与交换排序 题解(双端队列模拟区间反转)
    动态最小生成树 题解(线段树+归并排序)
    系数 题解(lucas+思维)
    D. Dogeforces 题解(并查集+构造)
    Java 入土基础
    E. AZ Graph 题解(思维)
  • 原文地址:https://www.cnblogs.com/ztlztl/p/12296674.html
Copyright © 2011-2022 走看看