Very Long Suffix Array
题解:
原来动态开点平衡树是O(n)空间的。。
只需要在split的查找和出来之后动态开点就可以了
这题的结论是2^(b[a[i]+1]>b[a[i+1]+1]的个数)
前60分是普通的平衡树操作完之后再算
满分是动态开点平衡树
对于一个点内部的统计一下,边界上的特判一下
#include <bits/stdc++.h> using namespace std; #define rint register int #define IL inline #define rep(i,h,t) for (int i=h;i<=t;i++) #define dep(i,t,h) for (int i=t;i>=h;i--) #define me(x) memset(x,0,sizeof(x)) #define ll long long #define mid ((h+t)>>1) #define mep(x,y) memcpy(x,y,sizeof(y)) namespace IO { char ss[1<<24],*A=ss,*B=ss; IL char gc() { return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++; } template<class T>void read(T &x) { rint f=1,c;while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48); while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f; } char sr[1<<24],z[20]; int C=-1,Z; template<class T>void wer(T x) { if (x<0) sr[++C]='-',x=-x; while (z[++Z]=x%10+48,x/=10); while (sr[++C]=z[Z],--Z); } IL void wer1() {sr[++C]=' ';} IL void wer2() {sr[++C]='\n';} template<class T>IL void maxa(T &x,T y) { if (x<y) x=y;} template<class T>IL void mina(T &x,T y) { if (x>y) x=y;} template<class T>IL T MAX(T x,T y){ return x>y?x:y;} template<class T>IL T MIN(T x,T y){ return x<y?x:y;} } using namespace IO; const int N=9e5; int a[N],b[N],xl[N],cnt,dy[N],d[N],tmp; const int mo=1e9+7; struct re{ int a,b,kk,d; }c[N],f[N],p[N],c1[N]; int nq; struct phs{ int fa[N],rs[N],ls[N],num[N],o[N],v[N],cnt,cnt3; bool rev[N],t[N]; IL void updata(int x) { num[x]=num[ls[x]]+num[rs[x]]+o[x]; } IL void down(int x) { if (rev[x]) { swap(ls[ls[x]],rs[ls[x]]); swap(ls[rs[x]],rs[rs[x]]); rev[ls[x]]^=1; rev[rs[x]]^=1; t[ls[x]]^=1; t[rs[x]]^=1; rev[x]=0; } } void rotate(int x,int y) { int f1=fa[x]; if (y==1) { rs[f1]=ls[x]; if (ls[x]) fa[ls[x]]=f1; } else { ls[f1]=rs[x]; if (rs[x]) fa[rs[x]]=f1; } fa[x]=fa[f1]; if (fa[f1]) { if (ls[fa[f1]]==f1) ls[fa[f1]]=x; else rs[fa[f1]]=x; } fa[f1]=x; if (y==1) ls[x]=f1; else rs[x]=f1; updata(f1); updata(x); } void dfs(int x) { if (fa[x]) dfs(fa[x]); down(x); } IL void splay(int x,int y) { dfs(x); int f1=fa[x]; while (f1!=y) { if (fa[f1]==y) if (ls[f1]==x) rotate(x,2); else rotate(x,1); else if (ls[fa[f1]]==f1) if (ls[f1]==x) rotate(f1,2),rotate(x,2); else rotate(x,1),rotate(x,2); else if (rs[f1]==x) rotate(f1,1),rotate(x,1); else rotate(x,2),rotate(x,1); f1=fa[x]; } } IL int sc(int x,int y) { if (t[x]) { o[++nq]=y; num[nq]=y; fa[nq]=x; v[nq]=v[x]; ls[nq]=ls[x]; o[x]-=y; v[x]+=y; ls[x]=nq; t[nq]=t[x]; } else { o[++nq]=y; num[nq]=y; fa[nq]=x; v[nq]=v[x]+o[x]-y; ls[nq]=ls[x]; o[x]-=y; ls[x]=nq; t[nq]=t[x]; } if (ls[nq]) fa[ls[nq]]=nq; num[nq]+=num[ls[nq]]; return nq; } IL int search(int y) { splay(1,0); int x=1; while (1) { down(x); if (num[ls[x]]+o[x]>=y&&num[ls[x]]<y) { if (num[ls[x]]+o[x]==y) return(x); return sc(x,y-num[ls[x]]); } if (num[ls[x]]+o[x]>y) x=ls[x]; else y-=num[ls[x]]+o[x],x=rs[x]; } } IL int split(int x,int y) { int k1=search(x),k2=search(y+2); splay(k1,0); splay(k2,k1); if (o[k2]!=1) sc(k2,o[k2]-1); return ls[k2]; } IL void reverse(int x,int y) { int k=split(x,y); rev[k]^=1; swap(ls[k],rs[k]); t[k]^=1; } IL void change(int x,int y) { int k=split(x,y);; int now=fa[k]; ls[now]=0; fa[k]=0; splay(now,0); now=search(2); splay(now,0); down(now); down(1); rs[1]=k; fa[k]=1; splay(k,0); } void dfs2(int x) { down(x); if (ls[x]) dfs2(ls[x]); // a[++cnt]=v[x]; c[++cnt]=(re){v[x],o[x],t[x],cnt3+1}; cnt3+=o[x]; if (rs[x]) dfs2(rs[x]); } }S; bool cmp(re x,re y) { return x.a<y.a; } IL int pos(int x) { if (x>tmp) return(0); int h=1,t=S.cnt-2; while (h<t) { if (f[mid].a+f[mid].b-1>=x) t=mid; else h=mid+1; } if (f[h].kk) return f[h].d+x-f[h].a; else return f[h].d+f[h].b-1-(x-f[h].a); } IL int pos2(int x) { if (c[x].kk) return c[x].a; else return c[x].a+c[x].b-1; } IL int fsp(ll x,int y) { ll ans=1; while (y) { if (y&1) ans=ans*x%mo; x=x*x%mo; y>>=1; } return ans; } int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); int n,m; read(n); read(m); tmp=n; int cnt=0; nq=3; S.rs[1]=2; S.rs[2]=3; S.fa[2]=1; S.fa[3]=2; S.t[2]=1; S.o[1]=1; S.v[1]=0; S.o[2]=n; S.v[2]=1; S.o[3]=1; S.v[3]=n+1; S.splay(3,0); rep(i,1,m) { int kk,x,y; read(kk); read(x); read(y); if (kk==0) S.change(x,y); else S.reverse(x,y); } S.splay(1,0); S.dfs2(1); int l=S.cnt; rep(i,1,l-2) f[i]=c[i+1]; sort(f+1,f+l-2+1,cmp); cnt=0; rep(i,2,l-1) { if (c[i].b>=3) cnt+=c[i].b-2; if (c[i].kk) { if (c[i].b>=1&&i!=(l-1)) { int k1=c[i].a+c[i].b-1,k2=pos2(i+1); if (pos(k1+1)<pos(k2+1)) cnt++; } if (c[i].b>=2) { int k1=c[i].a+c[i].b-2,k2=c[i].a+c[i].b-1; if (pos(k1+1)<pos(k2+1)) cnt++; } } else { if (c[i].b>=1&&i!=(l-1)) { int k1=c[i].a,k2=pos2(i+1); if (pos(k1+1)<pos(k2+1)) cnt++; } if (c[i].b>=2) { int k1=c[i].a+c[i].b-1,k2=c[i].a+c[i].b-2; if (pos(k1+1)<pos(k2+1)) cnt++; } } } cout<<fsp(2,cnt)<<endl; return 0; }