UOJ 218 火车管理
http://uoj.ac/problem/218
思路:建立一个可持久化线段树,代表这个位置的火车是哪辆,然后再弄一个线段树维护答案。
如果询问,直接询问线段树。
如果区间压入,直接在主席树上面压入,然后更新线段树答案
如果弹出,那么直接找主席树当前位之前的火车是那辆,然后修改线段树答案,再修改当前主席树答案。
改题的时候蜜汁错误。。
#include<cstdio> #include<cmath> #include<cstring> #include<iostream> #include<algorithm> int tr[40000005],ls[40000005],tag[40000005],rs[40000005]; int tg[2000005],sum[2000005],sz,rt[500005],a[500005]; int n,m,ty; int read(){ int t=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} return t*f; } void pushdown(int k){ if (tag[k]==-1) return; if (!ls[k]) ls[k]=++sz; if (!rs[k]) rs[k]=++sz; tag[ls[k]]=tag[rs[k]]=tr[ls[k]]=tr[rs[k]]=tag[k]; tag[k]=-1; } void add(int &k,int kk,int l,int r,int x,int y,int v){ k=++sz;tag[k]=-1; if (x==l&&r==y){ tag[k]=tr[k]=v; return; } pushdown(kk); int mid=(l+r)>>1; ls[k]=ls[kk];rs[k]=rs[kk]; if (y<=mid) add(ls[k],ls[kk],l,mid,x,y,v); else if (x>mid) add(rs[k],rs[kk],mid+1,r,x,y,v); else add(ls[k],ls[kk],l,mid,x,mid,v),add(rs[k],rs[kk],mid+1,r,mid+1,y,v); } int query(int k,int l,int r,int pos){ if (!k||l==r) return tr[k]; pushdown(k); int mid=(l+r)>>1; if (pos<=mid) return query(ls[k],l,mid,pos); else return query(rs[k],mid+1,r,pos); } void pushdown(int k,int l,int r){ if (tg[k]==-1||l==r) return; tg[k*2]=tg[k*2+1]=tg[k]; int mid=(l+r)>>1; sum[k*2]=tg[k]*(mid-l+1); sum[k*2+1]=tg[k]*(r-mid); tg[k]=-1; } void modify(int k,int l,int r,int x,int y,int v){ pushdown(k,l,r); if (x==l&&r==y){ tg[k]=v;sum[k]=(r-l+1)*v; pushdown(k,l,r); return; } int mid=(l+r)>>1; if (y<=mid) modify(k*2,l,mid,x,y,v); else if (x>mid) modify(k*2+1,mid+1,r,x,y,v); else modify(k*2,l,mid,x,mid,v),modify(k*2+1,mid+1,r,mid+1,y,v); sum[k]=sum[k*2]+sum[k*2+1]; } int getsum(int k,int l,int r,int x,int y){ pushdown(k,l,r); if (x==l&&r==y){ return sum[k]; } int mid=(l+r)>>1,z=0; if (y<=mid) return getsum(k*2,l,mid,x,y); else if (x>mid) return getsum(k*2+1,mid+1,r,x,y); else return getsum(k*2,l,mid,x,mid)+getsum(k*2+1,mid+1,r,mid+1,y); } int main(){ n=read();m=read();ty=read(); int ans=0; for (int i=1;i<=m;i++){ rt[i]=rt[i-1]; int opt=read(),l=read();l=(l+ty*ans)%n+1; if (opt==2){ int x=query(rt[i],1,n,l); if (x){ int y=query(rt[x-1],1,n,l); add(rt[i],rt[i],1,n,l,l,y); modify(1,1,n,l,l,a[y]); } continue; } int r=read();r=(r+ty*ans)%n+1; if (l>r) std::swap(l,r); if (opt==1){printf("%d\n",ans=getsum(1,1,n,l,r));} else{ a[i]=read(); add(rt[i],rt[i],1,n,l,r,i); modify(1,1,n,l,r,a[i]); } } return 0; }