BZOJ3514: Codechef MARCH14 GERALD07加强版
题解:推荐黄学长的:http://hzwer.com/4358.html
#include<iostream> #include<cstdio> #include<cstdlib> #include<string> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #include<iomanip> #include<map> #include<queue> using namespace std; #define mem1(i,j) memset(i,j,sizeof(i)) #define mem2(i,j) memcpy(i,j,sizeof(i)) #define LL long long #define up(i,j,n) for(LL i=(j);i<=(n);i++) #define FILE "ti" #define poi vec #define eps 1e-10 #define mid ((l+r)>>1) const int maxn=202000,inf=1000000000,mod=1000000007; int read(){ LL x=0,f=1,ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0',ch=getchar();} return f*x; } inline bool cmax(int& a,int b){return a<b?a=b,true:false;} inline bool cmin(int& a,int b){return a>b?a=b,true:false;} int n,m,k,type; int x[maxn],y[maxn],t[maxn]; namespace LCT{ const int maxn=404000; int c[maxn][2],fa[maxn],rev[maxn],val[maxn],Min[maxn]; inline void updata(int o){Min[o]=val[o];cmin(Min[o],Min[c[o][1]]);cmin(Min[o],Min[c[o][0]]);} inline void revv(int x){rev[x]^=1,swap(c[x][0],c[x][1]);} inline void pushdown(int x){if(rev[x])rev[x]^=1,revv(c[x][0]),revv(c[x][1]);} inline bool isroot(int o){return c[fa[o]][1]!=o&&c[fa[o]][0]!=o;} inline void rotate(int x){ int y=fa[x],z=fa[y],d=(c[y][1]==x); if(!isroot(y))c[z][c[z][1]==y]=x; fa[y]=x;fa[x]=z;if(c[x][d^1])fa[c[x][d^1]]=y; c[y][d]=c[x][d^1];c[x][d^1]=y; updata(y),updata(x); } int q[maxn],top=0; inline void splay(int x){ q[++top]=x; for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i]; while(top)pushdown(q[top--]); while(!isroot(x)){ int y=fa[x]; if(!isroot(y)){ if(c[y][1]==x^c[fa[y]][1]==y)rotate(x); else rotate(y); } rotate(x); } } inline void access(int x){for(int t=0;x;t=x,x=fa[x])splay(x),c[x][1]=t,updata(x);} inline void makeroot(int x){access(x);splay(x);revv(x);} inline void cut(int x,int y){makeroot(x);access(y);splay(y);c[y][0]=fa[x]=0;updata(y);} inline void link(int x,int y){makeroot(x),fa[x]=y;} inline void solve(){ up(i,1,n)val[i]=m+1; up(i,1,m)val[i+n]=i; Min[0]=inf,val[0]=inf; up(i,1,m){ if(x[i]==y[i]){t[i]=i;continue;} makeroot(x[i]),access(y[i]),splay(y[i]); int w=c[y[i]][0]; while(c[w][0])w=c[w][0]; if(w==x[i]){ int u=x[Min[y[i]]],v=y[Min[y[i]]],p=Min[y[i]]; cut(p+n,v),cut(p+n,u); link(i+n,x[i]);link(i+n,y[i]); t[i]=p; } else link(x[i],i+n),link(y[i],i+n); } } }; namespace zhuxi{ const int maxn=3800000; int c[maxn][2],sum[maxn],rt[maxn],cnt=0; int key=0; inline void updata(int o){sum[o]=sum[c[o][1]]+sum[c[o][0]];} inline void insert(int& o,int x,int l,int r){ o=++cnt; if(l==r){sum[o]=sum[x]+1;return;} if(key>mid)c[o][0]=c[x][0],insert(c[o][1],c[x][1],mid+1,r); else c[o][1]=c[x][1],insert(c[o][0],c[x][0],l,mid); updata(o); } inline void init(int* h){up(i,1,m)key=t[i],insert(rt[i],rt[i-1],0,m);} inline int query(int u,int v,int l,int r){ int S=0; while(true){ if(key==l&&l==r){S+=sum[v]-sum[u];break;} if(key>mid)S+=sum[c[v][0]]-sum[c[u][0]],u=c[u][1],v=c[v][1],l=mid+1; else u=c[u][0],v=c[v][0],r=mid; } return S; } inline void solve(){ init(t); int last=0; while(k--){ int x=read(),y=read(); if(type)x^=last,y^=last; key=x-1; printf("%d\n",last=n-query(rt[x-1],rt[y],0,m)); } } }; int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); n=read(),m=read(),k=read(),type=read(); up(i,1,m)x[i]=read(),y[i]=read(); LCT::solve(); zhuxi::solve(); return 0; }