线段树分治样例不过(悬 3 关)
查看原帖
线段树分治样例不过(悬 3 关)
571147
zhlzt楼主2024/10/8 21:44
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int ans[maxn<<1],secu[maxn<<1],secv[maxn<<1];
int siz[maxn<<1],fath[maxn<<1],sta[maxn<<1],top;
vector<int>vec[maxn<<3];
map<pair<int,int>,int>app;
inline int find(int u){
	while(u!=fath[u]) u=fath[u];
	return u;
}
inline void query(int p,int pl,int pr){
	int cnt=0,tag=0,fu,fv;
	for(int cur:vec[p]){
		fu=find(secu[cur]),fv=find(secv[cur]);
		if(fu==fv){tag=1;break;}
		if(siz[fu]<siz[fv]) swap(fu,fv);
		fath[fv]=fu,siz[fu]+=siz[fv];
		sta[++top]=fv,++cnt;
	}
	if(!tag){
		if(pl==pr) ans[pl]=1;
		else{
			int mid=(pl+pr)>>1;
			query(p<<1,pl,mid);
			query(p<<1|1,mid+1,pr);
		}
	}
	while(cnt--){
		fu=sta[top--];
		siz[fath[fu]]-=siz[fu];
		fath[fu]=fu;
	}
	return;
} 
inline void update(int l,int r,int p,int pl,int pr,int k){
	if(l<=pl and pr<=r){vec[p].push_back(k); return;}
	int mid=(pl+pr)>>1;
	if(l<=mid) update(l,r,p<<1,pl,mid,k);
	if(r>mid) update(l,r,p<<1|1,mid+1,pr,k);
	return;
}
int main(){
//	freopen("zyfakioi.in","r",stdin);
//	freopen("zyfakioi.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int n,m;cin>>n>>m;
	int u,v;
	for(int i=1;i<=n+n;i++) fath[i]=i,siz[i]=1;
	for(int i=1;i<=m;i++){
		cin>>secu[i]>>secv[i],secv[i]+=n;
	}
	int k;cin>>k;
	for(int i=m+1;i<=m+k;i++){
		cin>>secu[i]>>secv[i],secv[i]+=n;
	}
	for(int i=1;i<=m+k;i++){
		u=secu[i],v=secv[i];
		if(app[{u,v}] and i>m){
			update(app[{u,v}],i-1,1,1,m+k,app[{u,v}]);
			app.erase({u,v});
		} 
		else app[{u,v}]=i;
	}
	for(auto it=app.begin();it!=app.end();it++){
		update(it->second,k,1,1,m+k,(it->second));
	}
	query(1,1,m+k);
	for(int i=m+1;i<=m+k;i++){
		cout<<(ans[i]?"No\n":"Yes\n");
	}
	return 0;
}
2024/10/8 21:44
加载中...