JSOI2008火星人
Posted HellPix
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JSOI2008火星人相关的知识,希望对你有一定的参考价值。
题面
https://www.luogu.org/problem/P4036
题解
#include<cstdio> #include<iostream> #include<cstring> #define ri register int #define N 105000 #define uLL unsigned long long using namespace std; const uLL p=107; uLL pp[N]; char s[N],op[3],c[5]; int n,a,b,ptt; struct Splay{ int ch[N][2],f[N],siz[N]; uLL sum[N],v[N]; int tot; void clear() {tot=1; siz[1]=1;} // &&&*** bool opt(int x) {return ch[f[x]][1]==x;} int new_node(int x,int ff) { ++tot; sum[tot]=v[tot]=x; // &&&*** siz[tot]=1; f[tot]=ff; return tot; } void pushup(int x) { if (!x) return; // &&&*** siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; sum[x]=sum[ch[x][0]]+v[x]*pp[siz[ch[x][0]]]+sum[ch[x][1]]*pp[siz[ch[x][0]]+1]; } void rotate(int x) { int y=f[x],z=f[y],s=opt(x),w=ch[x][1^s]; f[x]=z; ch[z][opt(y)]=x; ch[y][s]=w; if (w) f[w]=y; f[y]=x; ch[x][1^s]=y; pushup(y); pushup(x); } void splay(int at,int to) { while (1) { if (f[at]==to) return; if (f[f[at]]==to) rotate(at); else { if (opt(at)==opt(f[at])) rotate(f[at]),rotate(at); else rotate(at),rotate(at); } } } int findbyrank(int x){ int les=0,now=1; while (1) { if (les+siz[ch[now][0]]==x) return now; else if (les+siz[ch[now][0]]>x) now=ch[now][0]; else les+=siz[ch[now][0]]+1,now=ch[now][1]; } } uLL getval(int l,int r) { int x=findbyrank(l-1); splay(x,1); if (r==ptt) return sum[ch[x][1]]; else { int y=findbyrank(r+1); splay(y,x); return sum[ch[y][0]]; // &&&*** } } } t; int main() { //freopen("tt.in","r",stdin); pp[0]=1; for (ri i=1;i<N;i++) pp[i]=pp[i-1]*p; scanf("%s",s+1); int L=strlen(s+1); t.clear(); for (ri i=1;i<=L;i++) { int x=t.findbyrank(i-1); t.splay(x,1); t.ch[x][1]=t.new_node(s[i]-‘a‘,x); t.pushup(x); } scanf("%d",&n); ptt=L; while (n--) { scanf("%s",op); if (op[0]==‘Q‘) { scanf("%d %d",&a,&b); int Lb=1,Rb=min(ptt-a+1,ptt-b+1),ans=0; while (Lb<=Rb) { int mid=(Lb+Rb)/2; uLL t1=t.getval(a,a+mid-1); uLL t2=t.getval(b,b+mid-1); //cout<<t1<<" "<<t2<<endl; if (t1==t2) ans=mid,Lb=mid+1; else Rb=mid-1; } printf("%d\n",ans); } else if (op[0]==‘I‘) { scanf("%d %s",&a,c); int x=t.findbyrank(a); t.splay(x,1); if (a==ptt) { t.ch[x][1]=t.new_node(c[0]-‘a‘,x); t.pushup(x); } else { int y=t.findbyrank(a+1); t.splay(y,x); t.ch[y][0]=t.new_node(c[0]-‘a‘,y); // &&&*** t.pushup(y); t.pushup(x); // &&&*** } ptt++; } else if (op[0]==‘R‘) { scanf("%d %s",&a,c); int x=t.findbyrank(a); t.splay(x,1); t.v[x]=c[0]-‘a‘; t.pushup(x); } } return 0; }
以上是关于JSOI2008火星人的主要内容,如果未能解决你的问题,请参考以下文章