제출 #1336972

#제출 시각아이디문제언어결과실행 시간메모리
1336972liptonek열쇠 (IOI21_keys)C++20
100 / 100
1113 ms114772 KiB
#include <bits/stdc++.h>
using namespace std;

const int MAX_N=300005;
const int INF=1e9+7;

set<pair<int,int>> wait[MAX_N]; 
vector<int> todo[MAX_N];        
set<int> has[MAX_N];   

int sz[MAX_N];
int id[MAX_N];
int vis[MAX_N];
int timer=0;

vector<int> nodes[MAX_N];      

void merge(int u, int v) 
{
    u=id[u];
	v=id[v];
    
	if(u==v) 
	{
		return;
	}
    
	if(sz[u]>sz[v]) 
	{
		swap(u,v);
	}

    sz[v]+=sz[u];
    
	for(int x : nodes[u]) 
	{
        nodes[v].push_back(x);
    
		id[x]=v;
    }
    
	nodes[u].clear();

    for(int x : todo[u]) 
	{
		todo[v].push_back(x);
	}
    
	todo[u].clear();

    for(auto &e : wait[u]) 
	{
        if(has[v].count(e.first)) 
		{
			todo[v].push_back(e.second);
		}
        else 
		{
			wait[v].insert(e);
		}
    }

    wait[u].clear();

    for(int k : has[u]) 
	{
        auto it=wait[v].lower_bound({k,-1});
    
		while(it!=wait[v].end() && it->first==k) 
		{
            todo[v].push_back(it->second);
            wait[v].erase(it++);
        }
        
		has[v].insert(k);
    }

    has[u].clear();
}

vector<int> find_reachable(vector<int> r, vector<int> u, vector<int> v, vector<int> c) 
{
    int n=r.size();
	int m=u.size();

    for(int i=0; i<n; i++) 
	{
        has[i]={r[i]};
        sz[i]=1;
        id[i]=i;
        nodes[i]={i};
    
		todo[i].clear();
        wait[i].clear();
    
		vis[i]=0;
    }

    for(int i=0; i<m; i++) 
	{
        if(has[u[i]].count(c[i])) 
		{
			todo[u[i]].push_back(v[i]);
		}
        else 
		{
			wait[u[i]].insert({c[i],v[i]});
		}
        
        if(has[v[i]].count(c[i])) 
		{
			todo[v[i]].push_back(u[i]);
		}
        else 
		{
			wait[v[i]].insert({c[i],u[i]});
		}
    }

    int np=INF;
    
	vector<int> best;

    for(int i=0; i<n; i++) 
	{
        if(vis[id[i]]) 
		{
			continue;
		}
    
		timer++;
    
		int curr=id[i];
    
		vector<int> stack;

        while(true) 
		{
            vis[curr]=timer;
        
			if(todo[curr].empty()) 
			{
                if(sz[curr]<np) 
				{
                    np=sz[curr];
                    best=nodes[curr];
                } 
				else if(sz[curr]==np) 
				{
                    for(int x : nodes[curr]) 
					{
						best.push_back(x);
					}
                }

                break;
            }

            int target=todo[curr].back();
            
			todo[curr].pop_back();
            
			int next=id[target];

            if(curr==next) 
			{
				continue;
			}

            if(!vis[next]) 
			{
                stack.push_back(curr);
            
				curr=next;
            } 
			else if(vis[next]==timer) 
			{
                while(true) 
				{
                    int p=stack.back(); 
                    stack.pop_back();
                
					merge(curr,p);
                
					if(p==next) 
					{
						break;
					}
                }

                curr=id[curr];
                vis[curr]=timer;
            } 
			else 
			{
                break;
            }
        }
    }

    vector<int> res(n,0);

	for(int x : best) 
	{
		res[x]=1;
	}

	return res;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...