【BZOJ3514】— Codechef MARCH14 GERALD07加强版(LCT+主席树)

传送门


考虑按照编号依次把点加入
假设当前加入边ii,如果形成了环
将环上最小的边xx删去,并记f[i]=xf[i]=x

考虑一次询问l,rl,r
如果i[l,r],f[i][l,r]i\in[l,r],f[i]\in[l,r]
那么边ii加进去就不会形成连通块

于是考虑统计满足这样的ii的个数
用主席树就完了

#include<bits/stdc++.h>
using namespace std;
const int RLEN=1<<20|1;
inline char gc(){
	static char ibuf[RLEN],*ib,*ob;
	(ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
	return (ob==ib)?EOF:*ib++;
}
#define gc getchar
inline int read(){
	char ch=gc();
	int res=0,f=1;
	while(!isdigit(ch))f^=ch=='-',ch=gc();
	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
	return f?res:-res;
}
#define ll long long
#define re register
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cs const
const int mod=998244353,g=3;
inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
inline void Add(int &a,int b){a=add(a,b);}
inline int dec(int a,int b){return a>=b?a-b:a-b+mod;}
inline void Dec(int &a,int b){a=dec(a,b);}
inline int mul(int a,int b){return 1ll*a*b>=mod?1ll*a*b%mod:a*b;}
inline void Mul(int &a,int b){a=mul(a,b);}
inline int ksm(int a,int b,int res=1){for(;b;b>>=1,a=mul(a,a))(b&1)?(res=mul(res,a)):0;return res;}
inline void chemx(int &a,int b){a<b?a=b:0;}
inline void chemn(int &a,int b){a>b?a=b:0;}
cs int N=400005;
namespace Lct{
	int fa[N],son[N][2],mn[N],id[N],val[N],rev[N];
	#define lc(u) son[u][0]
	#define rc(u) son[u][1]
	inline bool isrc(int u){
		return rc(fa[u])==u;
	}
	inline bool isrt(int u){
		return lc(fa[u])!=u&&rc(fa[u])!=u;
	}
	inline void pushup(int u){
		id[u]=u,mn[u]=val[u];
		if(lc(u)&&mn[lc(u)]<mn[u])mn[u]=mn[lc(u)],id[u]=id[lc(u)];
		if(rc(u)&&mn[rc(u)]<mn[u])mn[u]=mn[rc(u)],id[u]=id[rc(u)];
	}
	inline void pushdown(int u){
		if(!rev[u])return;
		if(lc(u))rev[lc(u)]^=1;
		if(rc(u))rev[rc(u)]^=1;
		swap(lc(u),rc(u));
		rev[u]=0;
	}
	inline void rotate(int v){
		int u=fa[v],z=fa[u];
		int t=rc(u)==v;
		fa[v]=z;
		if(!isrt(u))son[z][rc(z)==u]=v;
		fa[son[v][t^1]]=u,son[u][t]=son[v][t^1];
		son[v][t^1]=u,fa[u]=v;
		pushup(u),pushup(v);
	}
	int stk[N],top;
	inline void splay(int u){
		stk[top=1]=u;
		for(int v=u;!isrt(v);v=fa[v])stk[++top]=fa[v];
		for(int i=top;i;i--)pushdown(stk[i]);
		while(!isrt(u)){
			if(!isrt(fa[u]))
			isrc(u)==isrc(fa[u])?rotate(fa[u]):rotate(u);
			rotate(u);
		}
	}
	inline void access(int u){
		for(int v=0;u;v=u,u=fa[u]){
			splay(u),rc(u)=v;
			if(v)fa[v]=u;
			pushup(u);
		}
	}
	inline void makert(int u){
		access(u),splay(u),rev[u]^=1;
	}
	inline void link(int u,int v){
		makert(u),splay(v),fa[u]=v,pushup(v);
	}
	inline void cut(int u,int v){
		makert(u),access(v),splay(v);
		lc(v)=fa[u]=0;pushup(v);
	}
}
namespace Pt{
	cs int M=N*25;
	int tot,lc[M],rc[M],rt[N],siz[M];
	#define mid ((l+r)>>1)
	inline void insert(int r1,int &u,int l,int r,int p){
		u=++tot;
		siz[u]=siz[r1]+1,lc[u]=lc[r1],rc[u]=rc[r1];
		if(l==r)return;
		if(p<=mid)insert(lc[r1],lc[u],l,mid,p);
		else insert(rc[r1],rc[u],mid+1,r,p);
	}
	inline int query(int u,int l,int r,int st,int des){
		if(!u)return 0;
		if(st<=l&&r<=des)return siz[u];
		int res=0;
		if(st<=mid)res+=query(lc[u],l,mid,st,des);
		if(mid<des)res+=query(rc[u],mid+1,r,st,des);
		return res;
	}
}
int n,m,q,last,tp;
int f[N];
struct edge{
	int u,v;
}e[N];
int fa[N];
inline int find(int x){
	return fa[x]==x?x:fa[x]=find(fa[x]);
}
int main(){
	n=read(),m=read(),q=read(),tp=read();
	for(int i=1;i<=n;i++)Lct::val[i]=1e9,fa[i]=i;
	for(int i=1;i<=m;i++){
		e[i].u=read(),e[i].v=read();
		Lct::val[i+n]=i;
	}
	for(int i=1;i<=m;i++){
		int u=e[i].u,v=e[i].v;
		if(u==v){f[i]=i;continue;}
		int f1=find(u),f2=find(v);
		if(f1!=f2){
			fa[f1]=f2,Lct::link(i+n,u),Lct::link(i+n,v);
		}
		else{
			Lct::makert(u),Lct::access(v),Lct::splay(v);
			int mpos=Lct::id[v]-n;f[i]=mpos;
			Lct::cut(e[mpos].u,mpos+n),Lct::cut(e[mpos].v,mpos+n);
			Lct::link(i+n,u),Lct::link(i+n,v);
		}
	}
	for(int i=1;i<=m;i++)if(f[i])Pt::insert(Pt::rt[i-1],Pt::rt[i],1,m,f[i]);else Pt::rt[i]=Pt::rt[i-1];
	while(q--){
		int l=read()^(last*tp),r=read()^(last*tp);
		int del=Pt::query(Pt::rt[r],1,m,l,r)-Pt::query(Pt::rt[l-1],1,m,l,r);
		cout<<(last=(n-(r-l+1)+del))<<'\n';
	}
}
posted @ 2019-08-30 21:14  Stargazer_cykoi  阅读(120)  评论(0编辑  收藏  举报