我的思路 : 考虑每一对 (u,v) , 显然只有最开始 (u,v) 和 (u−1,v−1) 这样的操作 1 能让这一条边的状态改变 . 于是 (u,v) 和 (u−1,v−1) 把时间轴分成了好多段 , 每一段中这条边的状态都取决于这一段最前面那个点有没有改变状态 . 于是进行线段树分治 , 在第一次找到这个段的时候看一看是否会改变 .
#include<bits/stdc++.h>
#define ffor(i,a,b) for(int i=(a);i<=(b);i++)
#define roff(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
const int MAXN=8e5+10;
int n,m,lstans,op[MAXN],x[MAXN],y[MAXN],cnt,f[MAXN<<1];
map<pair<int,int>,vector<int>> mp;
map<pair<int,int>,int> stat;
//=====并查集=====
int fa[MAXN],sze[MAXN];
int find(int k) {return (fa[k]==k)?k:(find(fa[k]));}
void merge(int u,int v,stack<int>& st) {
u=find(u),v=find(v);
if(sze[u]<sze[v]) swap(u,v);
if(u==v) return ;
st.push(v),sze[u]+=sze[v],fa[v]=u;
return ;
}
void roll_back(stack<int> &st) {
while(!st.empty()) {
int u=st.top(); st.pop();
sze[fa[u]]-=sze[u],fa[u]=u;
}
return ;
}
//=====线段树分治=====
struct Segment {int l,r,id;};
vector<Segment> seg[MAXN<<2];
#define lson (k<<1)
#define rson (k<<1|1)
#define mid (l+r>>1)
void update(int k,int l,int r,int x,int y,Segment st) {
if(x<=l&&r<=y) return seg[k].push_back(st),void();
if(x<=mid) update(lson,l,mid,x,y,st);
if(y>mid) update(rson,mid+1,r,x,y,st);
return ;
}
void solve(int k,int l,int r) {
stack<int> st;
for(auto pr:seg[k]) {
int u=pr.l,v=pr.r,id=pr.id;
if(f[id]==-1) {
int U=(x[l]+lstans-1)%n+1,V=(y[l]+lstans-1)%n+1;
if(U>V) swap(U,V);
f[id]=(U==u&&V==v);
stat[{u,v}]^=f[id];
}
}
for(auto pr:seg[k]) {
int u=pr.l,v=pr.r,id=pr.id;
if(stat[{u,v}]) merge(u,v,st);
}
int tmp=0;
if(l==r) if(op[l]==2) cout<<(tmp=(find((x[l]+lstans-1)%n+1)==find((y[l]+lstans-1)%n+1))),lstans=tmp;
if(l!=r) solve(lson,l,mid),solve(rson,mid+1,r);
roll_back(st);
return ;
}
int main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n>>m,memset(f,-1,sizeof(f));
ffor(i,1,n) fa[i]=i,sze[i]=1;
ffor(i,1,m) {
cin>>op[i]>>x[i]>>y[i];
if(x[i]>y[i]) swap(x[i],y[i]);
if(op[i]==1) mp[{min(x[i],y[i]),max(x[i],y[i])}].push_back(i);
}
for(auto pr:mp) {
int u=pr.first.first,v=pr.first.second,U=u-1,V=v-1;
if(U==0) U=n; if(V==0) V=n;
if(U>V) swap(U,V);
auto vc=pr.second;
if(mp.count({U,V})&&(U!=u||V!=v)) for(auto mzx:mp[{U,V}]) vc.push_back(mzx);
sort(vc.begin(),vc.end());
vc.push_back(m+1);
for(int i=0;i+1<vc.size();i++) {
int st=vc[i],ed=vc[i+1]-1;
++cnt;
update(1,1,m,st,ed,{u,v,cnt});
}
}
solve(1,1,m);
return 0;
}
求 debug 或者思路纠错 . 悬赏若干关注和膜拜 .