BZOJ1014 [JSOI2008]火星人prefix
我们可以使用二分答案来计算。
至于添加和修改操作我们可以使用Splay来维护复杂度O(mlogn)当然Splay常数很大。
BZOJ上长时间TLE,有dalao可以帮忙看看,luogu上能过。加个inline就行了。
#include<bits/stdc++.h> using namespace std; const int N=150005,mod=9875321; typedef long long ll; int size[N],fa[N],c[N][2],v[N],h[N],p[N],n,m,cnt,rt; char ch[N]; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline void update(int x) { size[x]=size[c[x][0]]+size[c[x][1]]+1; h[x]=(h[c[x][0]]+1ll*v[x]*p[size[c[x][0]]]%mod+1ll*h[c[x][1]]*p[size[c[x][0]]+1]%mod)%mod; } inline void rotate(int x,int &k) { int y=fa[x],z=fa[y],l,r; l=(c[y][1]==x);r=l^1; if(k==y)k=x;else c[z][c[z][1]==y]=x; fa[y]=x;fa[x]=z;fa[c[x][r]]=y; c[y][l]=c[x][r];c[x][r]=y; update(y);update(x); } inline void splay(int x,int &k) { while(x!=k) { int y=fa[x],z=fa[y]; if(y!=k) { if(c[y][0]==x^c[z][0]==y)rotate(x,k); else rotate(y,k); } rotate(x,k); } } inline int find(int x,int k) { if(size[c[x][0]]+1==k)return x; else if(size[c[x][0]]>=k)return find(c[x][0],k); else return find(c[x][1],k-size[c[x][0]]-1); } void insert(int k,int w) { int x=find(rt,k),y=find(rt,k+1); splay(x,rt);splay(y,c[x][1]); int z=++cnt;c[y][0]=z;fa[z]=y;v[z]=w; update(z);update(y);update(x); } inline int query(int k,int w) { int x=find(rt,k);int y=find(rt,k+w+1); splay(x,rt);splay(y,c[x][1]); int z=c[y][0]; return h[z]; } int solve(int x,int y) { int l=1,r=min(cnt-x,cnt-y)-1,ans=0; while(l<=r) { int mid=l+r>>1; if(query(x,mid)==query(y,mid))l=mid+1,ans=mid; else r=mid-1; } return ans; } void build(int l,int r,int f) { if(l>r)return; int mid=l+r>>1; fa[mid]=f;c[f][mid>=f]=mid;v[mid]=ch[mid]-'a'+1; if(l==r){ size[mid]=1;h[mid]=v[mid];return; } build(l,mid-1,mid);build(mid+1,r,mid); update(mid); } int main() { scanf("%s",ch+2); n=strlen(ch+2);int x,y; p[0]=1;for(int i=1;i<=150004;++i)p[i]=p[i-1]*27%mod;cnt=n+2; build(1,n+2,0);rt=(n+3)>>1; m=read();char s[5],d[5]; for(int i=1;i<=m;++i) { scanf("%s",s); if(s[0]=='Q'){ x=read();y=read();printf("%d\n",solve(x,y)); } else if(s[0]=='R'){ x=read();scanf("%s",d+1);x=find(rt,x+1);splay(x,rt); v[rt]=d[1]-'a'+1;update(rt); } else{ x=read();scanf("%s",d+1);insert(x+1,d[1]-'a'+1); } } return 0; }
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。