Small X in FIG.
Topic background and meaning of the questions
FIG X has a small, there are n points (numbered from 0), and not in the beginning of FIG.
Side, to which he sometimes added a two-way side (x to y). Small X will occasionally want to know
Whether a road link two points, and if no communication prior to the communication time t edging operation, he
Will have their own plus side is satisfied, otherwise he will get angry, and incorrectly record Next
Adding edges as the recorded x (x + nc)% n, y is recorded as (y + nc)% n. until
He next asked so far. X is a C set arbitrarily small value (0 is a start), of course,
It will be modified over his will.
Your task is to answer his every inquiry
Input Format
The total number of the first row of n, m, X represents the number of small and the operating point
Next m lines of a first character
"K": Next, a digital c, c represents the value of new small X
"R": The next two integers u, v, represents even a bidirectional edge
"T": The next three integers u, v, t, presents to ask connectivity u to v, t Italian
As already mentioned before justice
Guarantee: Loop-free (heavy side but
Output Format
For each output line of inquiry "Y" on behalf of small X satisfactory, "N" represents the angry little X
See sample sample data folder
data range
30% of the data for n <= 1000, m <= 3000
For the remaining data: n, m <= 300000
For all data: 0 <= t <= m (but it is possible to add the t-th forward edge does not exist
Tip: This question you finish AK, is not very happy about
sol: This is probably one of the disjoint-set sustainable bare title. While 300,000 two log looks not too little, but that is over. . .
#include <bits/stdc++.h> using namespace std; typedef int ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) {f|=(ch=='-'); ch=getchar();} while(isdigit(ch)) {s=(s<<3)+(s<<1)+(ch^48); ch=getchar();} return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) {putchar('-'); x=-x;} if(x<10) {putchar(x+'0'); return;} write(x/10); putchar((x%10)+'0'); } #define W(x) write(x),putchar(' ') #define Wl(x) write(x),putchar('\n') const int N=300005; inline void copy(int &x,int y,int l,int r); inline void Build(int &x,int l,int r); inline void Chag(int &x,int y,int l,int r,int Pos,int Val); inline int Que(int x,int l,int r,int Pos); int n,m,cnt=0,Now; int fa[N],sz[N]; vector<int>Jh[N]; int rt[N<<2]; #define PB push_back struct Node { int ls,rs,id; }T[N*105]; inline int gf(int x){return (x==fa[x])?(x):(fa[x]=gf(fa[x]));} inline void ubbon(int x,int y) { int i,xx=gf(x),yy=gf(y); if(xx==yy) { // cout<<"@@@@@"<<x<<' '<<y<<endl; copy(rt[Now],rt[Now-1],1,n); return; } if(sz[xx]<sz[yy]) swap(xx,yy); fa[yy]=xx; sz[xx]+=sz[yy]; int oo[2],t=0; copy(oo[t],rt[Now-1],1,n); for(i=0;i<Jh[yy].size();i++) { t^=1; oo[t]=0; Chag(oo[t],oo[t^1],1,n,Jh[yy][i],xx); Jh[xx].PB(Jh[yy][i]); } copy(rt[Now],oo[t],1,n); Jh[yy].clear(); } inline void Build(int &x,int l,int r) { x=++cnt; if(l==r) { T[x].id=l; return; } int mid=(l+r)>>1; Build(T[x].ls,l,mid); Build(T[x].rs,mid+1,r); } inline void copy(int &x,int y,int l,int r) { x=y; } inline void Chag(int &x,int y,int l,int r,int Pos,int Val) { x=++cnt; T[x]=T[y]; if(l==r) { T[x].id=Val; return; } int mid=(l+r)>>1; if(Pos<=mid) Chag(T[x].ls,T[y].ls,l,mid,Pos,Val); else Chag(T[x].rs,T[y].rs,mid+1,r,Pos,Val); } inline int Que(int x,int l,int r,int Pos) { if(l==r) return T[x].id; int mid=(l+r)>>1; if(Pos<=mid) return Que(T[x].ls,l,mid,Pos); else return Que(T[x].rs,mid+1,r,Pos); } int main() { freopen("history.in","r",stdin); freopen("history.out","w",stdout); int i,C=0,x,y,z,Last; char S[5]; R(n); R(m); for(i=1;i<=n;i++) {fa[i]=i; sz[i]=1; Jh[i].PB(i);} Build(rt[Now=0],1,n); // for(i=1;i<=n;i++) cout<<Que(rt[Now],1,n,i)<<' '; // putchar('\n'); int Test=0; while(m--) { scanf("%s",S+1); switch (S[1]) { case 'K': R(C); break; case 'R': R(x); R(y); x=(x+Last*C)%n; y=(y+Last*C)%n; x++; y++; // cout<<"RRR"<<' '<<x<<' '<<y<<endl; Now++; ubbon(x,y); break; case 'T': R(x); R(y); R(z); x++; y++; if(x==y) {puts("N"); Last=1; break;} int xx=gf(x),yy=gf(y); if(xx==yy) { if(Now<z) puts("Y"),Last=0; else { int c1=Que(rt[Now-z],1,n,x),c2=Que(rt[Now-z],1,n,y); if(c1==c2) puts("N"),Last=1; else puts("Y"),Last=0; } } else puts("N"),Last=1; // if(++Test==185) return 0; break; } // for(i=1;i<=n;i++) cout<<Que(rt[Now],1,n,i)<<' '; // putchar('\n'); } return 0; }