http://acm.hdu.edu.cn/showproblem.php?pid=6858
思路:尺取左右端,用LCT维护连通性。
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+100;
int T,n,m,q;
int x[maxn],y[maxn],ans[maxn];
struct Node *null;
struct Node{
Node *fa,*ch[2];
int val,sum,c;
bool reversed;
Node(){}
Node(int val):fa(null),val(val),sum(val),reversed(false){ch[0]=ch[1]=null;}
void maintain(){if(this!=null)this->sum=ch[0]->sum+ch[1]->sum+val;}
void reverse(){if(this!=null){reversed^=1;swap(ch[0],ch[1]);c=c==-1?-1:1-c;}}
void pushdown(){if(reversed){reversed=0;ch[0]->reverse();ch[1]->reverse();}}
}pool[maxn];
void rotate(Node *&o, int d)
{
Node *k=o->ch[d^1];
k->ch[d]->fa=o;k->fa=o->fa;o->fa=k;
o->ch[d^1]=k->ch[d];k->ch[d]=o;
o->maintain();k->maintain();
o=k;
}
void _splay(Node *&o)
{
o->pushdown();
if(o->c!=-1)
{
Node *k=o->ch[o->c];
k->pushdown();
if(k->c!=-1)
{
_splay(k->ch[k->c]);
if(o->c==k->c)rotate(o,o->c^1);
else rotate(o->ch[o->c],o->c);
}
rotate(o,o->c^1);
}
}
bool isRoot(Node *o){return o->fa==null||(o->fa->ch[0]!=o&&o->fa->ch[1]!=o);}
void splay(Node *o)
{
o->c=-1;
while(!isRoot(o))
{
if(o==o->fa->ch[0])o->fa->c=0;
else o->fa->c=1;
o=o->fa;
}
_splay(o);
}
Node *access(Node *o)
{
Node *k=null;
while(o!=null)
{
splay(o);
o->ch[1]=k;
o->maintain();
k=o;
o=o->fa;
}
while(k->ch[0]!=null)k=k->ch[0];
return k;
}
void makeRoot(Node *x)
{
access(x);
splay(x);
x->reverse();
}
void link(int x,int y)
{
makeRoot(pool+x);
(pool+x)->fa=pool+y;
}
bool connected(int x,int y)
{
return access(pool+x)==access(pool+y);
}
int Distance(int x,int y)
{
makeRoot(pool+x);
access(pool+y);
splay(pool+y);
return (pool+y)->sum;
}
void cut(int x,int y)
{
makeRoot(pool+x);
access(pool+y);
splay(pool+x);
(pool+x)->ch[1]->fa=null;
(pool+x)->ch[1]=null;
(pool+x)->maintain();
}
int main()
{
// freopen("input.in","r",stdin);
null=new Node();
cin>>T;
while(T--)
{
cin>>n>>m>>q;
for(int i=1;i<=n;i++)pool[i].fa=pool[i].ch[0]=pool[i].ch[1]=null,pool[i].reversed=false;
for(int i=1;i<=m;i++)scanf("%d%d",&x[i],&y[i]);
int l=1,r=1;
while(l<=m)
{
if(r>m){ans[l]=1e9;l++;continue;}
while(!connected(x[r],y[r]))
{
link(x[r],y[r]);
++r;
if(r>m)break;
}
if(r>m){ans[l]=1e9;l++;continue;}
ans[l]=r;
cut(x[l],y[l]);
l++;
}
int last=0;
int _l,_r,k1,k2;
while(q--)
{
scanf("%d%d",&_l,&_r);
k1=(_l^last)%m+1,k2=(_r^last)%m+1;
l=min(k1,k2),r=max(k1,k2);
if(ans[l]<=r)last=1;
else last=0;
puts(last?"Yes":"No");
}
}
//for(int i=1;i<=m;i++)cout<<ans[i]<<endl;
return 0;
}