Code:
#include<bits/stdc++.h> #define maxn 500005 using namespace std; int n,Q,ty,lastans=0; int rt[maxn], tim[maxn], lp[maxn], tp[maxn]; void setIO(string s) { string in=s+".in"; string out=s+".out"; freopen(in.c_str(),"r",stdin); freopen(out.c_str(),"w",stdout); } namespace tree1 { #define lson ( x<<1) #define rson ( (x<<1)|1) int sumv[500005<<2],lazy[500005<<2]; void mark(int l,int r,int x,int k) { sumv[x]=(r-l+1)*k; lazy[x]=k; } void pushup(int x) { sumv[x]=sumv[lson]+sumv[rson]; } void pushdown(int l,int r,int x) { if(!lazy[x]) return; int mid=(l+r)>>1; if(mid >= l) mark(l, mid, lson, lazy[x]); if(r > mid) mark(mid + 1, r, rson, lazy[x]); lazy[x]=0; } void update(int l,int r,int x,int L,int R,int k) { if(l>=L&&r<=R) { mark(l,r,x,k); return; } pushdown(l,r,x); int mid=(l+r)>>1; if(L<=mid) update(l,mid,lson,L,R,k); if(R>mid) update(mid+1,r,rson,L,R,k); pushup(x); } int query(int l,int r,int x,int L,int R) { if(l>=L&&r<=R) return sumv[x]; pushdown(l, r, x); int mid=(l+r)>>1, tmp=0; if(L<=mid) tmp+=query(l,mid,lson,L,R); if(R>mid) tmp+=query(mid+1,r,rson,L,R); return tmp; } #undef lson #undef rson }; namespace tree2 { int tot=0; int tag[maxn*75],value[maxn*75]; int lson[maxn*75],rson[maxn*75]; void mark(int x,int delta) { value[x]=tag[x]=delta; return; } void pushdown(int l,int r,int x) { if(!tag[x]) return; int mid=(l+r)>>1; if(mid>=l && !lson[x]) lson[x]=++tot; if(r > mid && !rson[x]) rson[x]=++tot; if(lson[x]) mark(lson[x], tag[x]); if(rson[x]) mark(rson[x], tag[x]); tag[x]=0; } void add(int &k,int kk,int l,int r,int L,int R,int delta) { tag[k=++tot]=0; if(l>=L&&r<=R) { mark(k, delta); return; } int mid=(l+r)>>1; pushdown(l,r,kk); lson[k]=lson[kk], rson[k]=rson[kk]; if(L <= mid) add(lson[k], lson[kk], l, mid, L, R, delta); if(R > mid) add(rson[k], rson[kk], mid + 1, r, L, R, delta); } int query(int l,int r,int k,int pos) { if(!k || l == r) return value[k]; pushdown(l,r,k); int mid=(l+r)>>1; if(pos<=mid) return query(l,mid,lson[k], pos); else return query(mid+1,r,rson[k],pos); } }; int main() { // setIO("input"); scanf("%d%d%d",&n,&Q,&ty); int opt,l,r,dd; for(int i=1;i<=Q;++i) { scanf("%d",&opt); switch(opt) { case 1 : { scanf("%d%d",&l,&r); l=(l+lastans*ty)%n+1; r=(r+lastans*ty)%n+1; if(l>r) swap(l,r); lastans=tree1::query(1,n,1,l,r); printf("%d\n",lastans); rt[i]=rt[i-1]; break; } case 2 : { scanf("%d",&l); l=(l+lastans*ty)%n+1; int o = tree2::query(1, n, rt[i-1],l); //查询修改的 l 的修改操作. if(!o) rt[i]=rt[i-1]; else { int oo = tree2::query(1,n,rt[o-1],l); // 上一次操作 tree1::update(1,n,1,l,l,tp[oo]); // tree2::add(rt[i], rt[i-1], 1, n, l,l,oo); } break; } case 3 : { scanf("%d%d%d",&l,&r,&dd); l=(l+lastans*ty)%n+1; r=(r+lastans*ty)%n+1; if(l>r) swap(l,r); tp[i]=dd; tree1::update(1,n,1,l,r,dd); tree2::add(rt[i],rt[i-1],1,n,l,r,i); break; } } } return 0; }