Submission #1017958

#TimeUsernameProblemLanguageResultExecution timeMemory
1017958pccParachute rings (IOI12_rings)C++17
100 / 100
999 ms161400 KiB
#include <bits/stdc++.h>
using namespace std;

#define pii pair<int,int>
#define fs first
#define sc second

const int mxn = 1e6+10;

int phase;
int N;
bool initflag = false;

struct DSU{
	int cnt[mxn][4];//deg = 0,deg = 1,deg = 2,deg>2
	int dsu[mxn],sz[mxn],deg[mxn];
	int good,cycle;
	int WA = false;
	void init(int n){
		good = true;
		cycle = -1;
		for(int i = 0;i<n;i++){
			dsu[i] = i,sz[i] = 1;
			memset(cnt[i],0,sizeof(cnt[i]));
			cnt[i][0] = 1;
		}
		return;
	}
	int root(int k){
		return k == dsu[k]?k:dsu[k] = root(dsu[k]);
	}
	void check(int a){
		a = root(a);
		if(cnt[a][3])good = false,cycle = -1;
		else if(!cnt[a][1]&&cycle != -1)WA = true;
		else if(!cnt[a][1])cycle = a;
		return;
	}
	void del(int k){
		int r = root(k);
		cnt[r][min(deg[k],3)]--;
		return;
	}
	void add(int k){
		int r = root(k);
		cnt[r][min(deg[k],3)]++;
		return;
	}
	void add_edge(int a,int b){
		del(a);deg[a]++;add(a);
		del(b);deg[b]++;add(b);
		a = root(a),b = root(b);
		if(a != b){
			if(sz[a]<sz[b])swap(a,b);
			dsu[b] = a;
			sz[a] += sz[b];
			for(int i = 0;i<4;i++)cnt[a][i] += cnt[b][i];
		}
		check(a);
		return;
	}
};

vector<pii> edges;


namespace PHASE1{
	DSU dsu;
	void INIT(){
		//cerr<<"PHASE 1 init!"<<endl;
		dsu.init(N);
		//cerr<<"PHASE 1 INIT DONE!"<<endl;
	}
	void ADD(int a,int b){
		//cerr<<"PHASE 1 add: "<<a<<','<<b<<endl;
		dsu.add_edge(a,b);
		if(!dsu.good){
			phase = 2;
			initflag = true;
		}
		//cerr<<"PHASE 1 add done!"<<endl;
		return;
	}
	int CALC(){
		//cerr<<"PHASE 1 CALC"<<endl;
		if(dsu.WA)return 0;
		if(dsu.cycle != -1)return dsu.sz[dsu.root(dsu.cycle)];
		else return N;
	}
}

namespace PHASE2{
	struct GRAPH{
		DSU dsu;
		int ban;
		GRAPH(int k = -1){
			ban = k;
			dsu.init(N);
		}
		void add_edge(int a,int b){
			if(a == ban||b == ban)return;
			dsu.add_edge(a,b);
			//cerr<<"ADD_EDGE: "<<ban<<','<<a<<' '<<b<<':'<<dsu.cycle<<endl;
			return;
		}
		bool isgood(){
			return dsu.good&&dsu.cycle == -1;
		}
	};

	GRAPH v[5];
	int ptr = 0;
	void INIT(){
		//cerr<<"PHASE 2 INIT!"<<endl;
		//cerr<<"PHASE 2 INIT!"<<endl;
		int fat = -1;
		ptr = 0;
		for(int i = 0;i<N;i++)if(PHASE1::dsu.deg[i] >= 3)fat = i;
		assert(fat != -1);
		v[ptr++].ban = fat;
		for(auto &i:edges){
			if(i.fs == fat)v[ptr++].ban = i.sc;
			if(i.sc == fat)v[ptr++].ban = i.fs;
		}
		for(int i = 0;i<ptr;i++)v[i].dsu.init(N);
		//cerr<<"SPECIALS: ";for(int i = 0;i<ptr;i++)cerr<<v[i].ban<<' '<<v[i].dsu.cycle<<',';cerr<<endl;
		for(auto &i:edges){
			for(int j = 0;j<ptr;j++)v[j].add_edge(i.fs,i.sc);
		}
		//cerr<<"SPECIALS: ";for(int i = 0;i<ptr;i++)cerr<<v[i].ban<<' '<<v[i].dsu.cycle<<',';cerr<<endl;
		//cerr<<"PHASE 2 INIT DONE!"<<endl;
	}
	void ADD(int a,int b){
		//cerr<<"PHASE 2 ADD: "<<a<<','<<b<<endl;
		for(int i = 0;i<ptr;i++)v[i].add_edge(a,b);
		//cerr<<"PHASE 2 ADD DONE!"<<endl;
		return;
	}
	int CALC(){
		//cerr<<"PHASE 2 CALC"<<endl;
		if(PHASE1::dsu.WA)return 0;
		int ans = 0;
		for(int i = 0;i<ptr;i++)ans += v[i].isgood();
		return ans;
	}
}

void Init(int N_) {
	edges.clear();
	phase = 1;
	N = N_;
	PHASE1::INIT();
}

void Link(int A, int B) {
	edges.push_back(pii(A,B));
	if(phase == 1)PHASE1::ADD(A,B);
	else PHASE2::ADD(A,B);
	if(initflag){
		//cerr<<"PHASE 2 INIT!"<<endl;
		PHASE2::INIT();
		initflag = false;
	}
	return;
}

int CountCritical() {
	if(phase == 1)return PHASE1::CALC();
	else return PHASE2::CALC();
}
#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...