[bzoj3514]Codechef MARCH14 GERALD07加强版
LCT
- 代码
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
const int INF=0x3f3f3f3f;
namespace LinkCutTree{
struct Splay{
int ch[2],fa;
int sz;bool rev;
int val,minval;
}t[N];
int cnt,null;
int newnode(int _val){
++cnt;t[cnt].fa=t[cnt].ch[0]=t[cnt].ch[1]=0,t[cnt].sz=1,t[cnt].rev=0;
t[cnt].minval=t[cnt].val=_val;
return cnt;
}
bool isroot(int x){return t[t[x].fa].ch[0]!=x&&t[t[x].fa].ch[1]!=x;}
bool son(int x){return t[t[x].fa].ch[1]==x;}
void pushup(int x){
t[x].sz=1,t[x].minval=t[x].val;
if(t[x].ch[0])t[x].sz+=t[t[x].ch[0]].sz,t[x].minval=min(t[x].minval,t[t[x].ch[0]].minval);
if(t[x].ch[1])t[x].sz+=t[t[x].ch[1]].sz,t[x].minval=min(t[x].minval,t[t[x].ch[1]].minval);
}
inline void rotate(int x){
int f=t[x].fa,g=t[t[x].fa].fa;
bool a=son(x),b=son(x)^1;
if(!isroot(f))t[g].ch[son(f)]=x;
t[x].fa=g;
t[t[x].ch[b]].fa=f;t[f].ch[a]=t[x].ch[b];
t[x].ch[b]=f;t[f].fa=x;
pushup(f);pushup(x);
}
inline void pushnow(int x){
if(t[x].rev) {
swap(t[x].ch[1],t[x].ch[0]);t[x].rev=0;
if(t[x].ch[1])t[t[x].ch[1]].rev^=1;
if(t[x].ch[0])t[t[x].ch[0]].rev^=1;
}
}
inline void pushdown(int x){
if(!isroot(x))pushdown(t[x].fa);
pushnow(x);
}
inline void splay(int x){
pushdown(x);
while(!isroot(x)){
int f=t[x].fa;
if(!isroot(f)){
if(son(x)^son(f))rotate(x);
else rotate(f);
}
rotate(x);
}
}
inline void access(int x){
int tmp=null;
do{
splay(x);
t[x].ch[1]=tmp;
pushup(x);
tmp=x;x=t[x].fa;
}while(x!=null);
}
inline void makeroot(int x){
access(x);
splay(x);
t[x].rev^=1;
}
inline void cut(int x,int y){
makeroot(x);
access(y);
splay(y);
t[y].ch[1]=null;
t[x].fa=null;
pushup(y);
}
inline void link(int x,int y){
makeroot(y);
access(x);
t[x].ch[1]=y;
t[y].fa=x;
pushup(x);
}
inline int findmin(int u,int v){
makeroot(u);
access(v);
splay(v);
return t[v].minval;
}
}
/*LCT*/
using namespace LinkCutTree;
int Trt[N];
namespace SegTree{
int t[N*20],cnt,lch[N*20],rch[N*20];
inline int add(int &x,int pre,int l,int r,int pos,int sum){
if(!x)x=++cnt;
int mid=(l+r)>>1;
t[x]=t[pre]+sum;
if(l==r)return x;
if(pos<=mid)lch[x]=add(lch[x],lch[pre],l,mid,pos,sum),rch[x]=rch[pre];
else rch[x]=add(rch[x],rch[pre],mid+1,r,pos,sum),lch[x]=lch[pre];
return x;
}
inline int qry(int x,int l,int r,int ql,int qr){
int mid=(l+r)>>1;
if(!x)return 0;
if(ql<=l&&qr>=r)return t[x];
int ret=0;
if(ql<=mid)
ret+=qry(lch[x],l,mid,ql,qr);
if(qr>mid)
ret+=qry(rch[x],mid+1,r,ql,qr);
return ret;
}
}
using namespace SegTree;
int id_n[N],u[N],v[N],id_e[N];
int n,m,k,type;
int par[N];
inline int find(int x){
return par[x]==x?par[x]:par[x]=find(par[x]);
}
int main()
{
scanf("%d%d%d%d",&n,&m,&k,&type);
for(int i=1;i<=n;i++){
id_n[i]=newnode(INF);
par[i]=i;
}
for(int i=1;i<=m;i++){
scanf("%d%d",&u[i],&v[i]);
id_e[i]=newnode(i);
if(u[i]==v[i]){
add(Trt[i],Trt[i-1],1,m,i,1);
continue;
}
int x=find(u[i]),y=find(v[i]);
if(x^y){
Trt[i]=Trt[i-1];
par[x]=y;
link(id_n[v[i]],id_e[i]);
link(id_n[u[i]],id_e[i]);
}else{
int pos=findmin(id_n[u[i]],id_n[v[i]]);
add(Trt[i],Trt[i-1],1,m,pos,1);
int xx=id_n[u[pos]],yy=id_n[v[pos]];
cut(id_e[pos],xx);
cut(id_e[pos],yy);
link(id_e[i],id_n[u[i]]);
link(id_e[i],id_n[v[i]]);
}
}
int lastans=0;
for(int i=1;i<=k;i++){
int l,r;scanf("%d%d",&l,&r);
if(type==1){
l=l^lastans,r=r^lastans;
}
int ans=(r-l+1)-qry(Trt[r],1,m,l,m);
ans=n-ans;
printf("%d\n",ans);
lastans=ans;
}
}