bzoj1014火星人
...强迫症终于A了这道题 bzoj前30道全A指日可待
splay维护这个结点控制的字符串的hash值
每次旋转重新算一遍就可以了
查询的时候跑一个二分
讲起来很简单但是还是调了1h才调对了splay
把main写完饺子都凉了
没写过几次平衡树 常数写的奇大 能递归的我都递归了。。。
字符串哈希因为过于Naive只会用自然溢出。。。
但是1A了
家里的电脑有写好的read和write
我竟然忘了。。。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #include<vector> #include<queue> #include<set> #include<map> #include<stack> #define ll unsigned long long #define pi 3.14 #define eps 1e-9 #define inf 2147483233 #define m(a) memset(a,0,sizeof(a)) #define M(a) memset(a,127,sizeof(a)) #define REP(i,m,n) for(int i=1;i<=n;i++) #define DWN(i,n,m) for(int i=n;i>=1;i++) #define lowbit(x) x&(-x) using namespace std; int n; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=10*x+ch-'0';ch=getchar();} return x*f; } inline void write(int x) { int num=0; char buf[15]; while(x)buf[++num]=(x%10)+'0',x/=10; while(num)putchar(buf[num--]); putchar('\n'); } ll powe[150000]; void makepow() { int i; for(powe[0]=1,i=1;i<140142;i++)powe[i]=powe[i-1]*131; } const int maxn=140142; char str[maxn]; struct SplayTree { int rt,Size; int son[maxn][2],f[maxn],size[maxn]; ll val[maxn],hsh[maxn]; char s[maxn]; inline void pushup(int x){size[x]=size[son[x][0]]+size[son[x][1]]+1;hsh[x]=hsh[son[x][0]]+powe[size[son[x][0]]]*s[x]+powe[size[son[x][0]]+1]*hsh[son[x][1]];} inline void Rotate(int x,int type) { int y=f[x]; son[y][!type]=son[x][type]; f[son[x][type]]=y; f[x]=f[y]; if(f[x])son[f[y]][son[f[y]][1]==y]=x; son[x][type]=y; f[y]=x; size[x]=size[y],hsh[x]=hsh[y]; pushup(y); } inline void splay(int x,int goal) { while(f[x]!=goal) { if(f[f[x]]==goal) { if(son[f[x]][0]==x)Rotate(x,1); else Rotate(x,0); } else { int y=f[x],z=f[y]; if(son[z][0]==y) { if(son[y][0]==x)Rotate(y,1),Rotate(x,1); else Rotate(x,0),Rotate(x,1); } else { if(son[y][1]==x)Rotate(y,0),Rotate(x,0); else Rotate(x,1),Rotate(x,0); } } } if(goal==0) rt=x; } inline int rank(int x,int k) { if(k<=size[son[x][0]]) return rank(son[x][0],k); else if(k==size[son[x][0]]+1) return x; else return rank(son[x][1],k-size[son[x][0]]-1); } inline int build(int l,int r,int id) { if(l>r)return 0; int x=++Size,mid=(l+r)>>1; f[x]=id; s[x]=str[mid]; son[x][0]=build(l,mid-1,x); son[x][1]=build(mid+1,r,x); pushup(x); return x; } inline void insert(int k,char val) { int x=rank(rt,k),y=rank(rt,k+1); splay(x,0),splay(y,x); s[++Size]=val; f[Size]=y,son[y][0]=Size; pushup(Size); pushup(y); pushup(x); } inline void change(int k,int val) { int x=rank(rt,k); splay(x,0); s[x]=val; pushup(x); } inline int bisearch(int kx,int ky) { int l=0,r=n,mid; while(l<=r) { mid=l+r>>1; if(ky+mid>n+2) { r=mid-1; continue; } int x=rank(rt,kx-1),y=rank(rt,kx+mid); splay(x,0),splay(y,x); ll temp=hsh[son[y][0]]; x=rank(rt,ky-1),y=rank(rt,ky+mid); splay(x,0),splay(y,x); if(temp==hsh[son[y][0]])l=mid+1; else r=mid-1; } return r; } }splay; int main() { int m,i,j,k,x,y; char op[10],val[10]; scanf("%s%d",str+1,&m); makepow(); n=strlen(str+1); splay.rt=splay.build(0,n+1,0); for(i=1;i<=m;i++) { scanf("%s",op); if(op[0]=='I') { scanf("%d%s",&x,val); splay.insert(x+1,val[0]); n++; } else if(op[0]=='R') { scanf("%d%s",&x,val); splay.change(x+1,val[0]); } else { scanf("%d%d",&x,&y); if(x>y) swap(x,y); if(x!=y) printf("%d\n",splay.bisearch(x+1,y+1)); else printf("%d\n",n-x+1); } } return 0; }