这线段树还能不能好好用了╭(╯^╰)╮
然而Splay写起来太麻烦(虽然看起来好像很简单的样子,各种操作都支持)
于是还是滚回去用线段树,主要坑在旋转这个操作,因为线段树不能转。。。。所以只好让区间端点转一下了,所以每次操作的时候要先计算操作区间。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=500000+5; inline int read(){ int x=0;char ch; while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x; } struct data{int l,r,sum;}; struct seg{ int l,r,tag; data c; }tr[N*4]; bool rev; int n,d; void calc(int &x,int &y){ if(rev){ x=(n*2+2-d-x)%n; y=(n*2+2-d-y)%n; swap(x,y); }else{ x=(x+n-d)%n; y=(y+n-d)%n; } if(!x)x=n;if(!y)y=n; } inline data merge(data a,data b){ data tmp; tmp.l=a.l;tmp.r=b.r; tmp.sum=a.sum+b.sum; if(a.r==b.l)tmp.sum--; return tmp; } inline void pushup(int o){ tr[o].c=merge(tr[o<<1].c,tr[o<<1|1].c); } inline void pushdown(int o){ if(tr[o].tag&&tr[o].l!=tr[o].r){ tr[o<<1].tag=tr[o<<1|1].tag=tr[o<<1].c.l=tr[o<<1].c.r=tr[o<<1|1].c.l=tr[o<<1|1].c.r=tr[o].tag; tr[o<<1].c.sum=tr[o<<1|1].c.sum=1; tr[o].tag=0; } } void build(int o,int l,int r){ tr[o].l=l;tr[o].r=r; if(l==r){ tr[o].c.l=tr[o].c.r=read(); tr[o].c.sum=1; }else{ int m=l+r>>1; build(o<<1,l,m);build(o<<1|1,m+1,r); pushup(o); } } data query(int o,int a,int b){ pushdown(o); int l=tr[o].l,r=tr[o].r; if(l==a&&b==r)return tr[o].c; else{ int m=l+r>>1; if(b<=m)return query(o<<1,a,b); else if(m<a)return query(o<<1|1,a,b); else return merge(query(o<<1,a,m),query(o<<1|1,m+1,b)); } } void modify(int o,int a,int b,int v){ pushdown(o); int l=tr[o].l,r=tr[o].r; if(l==a&&b==r){ tr[o].c.l=tr[o].c.r=tr[o].tag=v; tr[o].c.sum=1; }else{ int m=l+r>>1; if(b<=m)modify(o<<1,a,b,v); else if(m<a)modify(o<<1|1,a,b,v); else{ modify(o<<1,a,m,v);modify(o<<1|1,m+1,b,v); } pushup(o); } } int main(){ int m;n=read();m=read(); build(1,1,n); int x,y,v; m=read(); char opt[10]; while(m--){ scanf("%s",opt); if(opt[0]=='R'){ v=read(); if(rev)d=(d+n-v)%n; else d=(d+v)%n; }else if(opt[0]=='F')rev^=1; else if(opt[0]=='S'){ x=read();y=read(); int a,b;data ans; calc(x,y); if(x<=y){ ans=query(1,x,y); a=ans.l;b=ans.r; }else{ ans=query(1,y,x); a=ans.r;b=ans.l; } modify(1,x,x,b);modify(1,y,y,a); }else if(opt[0]=='P'){ x=read();y=read();v=read(); calc(x,y); if(x<=y)modify(1,x,y,v); else{ modify(1,x,n,v); modify(1,1,y,v); } }else if(opt[0]=='C'&&opt[1]=='S'){ x=read();y=read(); calc(x,y); if(x<=y)printf("%d\n",query(1,x,y).sum); else printf("%d\n",merge(query(1,x,n),query(1,1,y)).sum); }else{ data ans=query(1,1,n); int tmp=ans.sum; if(ans.l==ans.r)tmp=max(tmp-1,1); printf("%d\n",tmp); } } return 0; }