题解:推荐黄学长的: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
",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;
}