【bzoj1014】: [JSOI2008]火星人prefix 平衡树-字符串-hash-二分

【bzoj1014】: [JSOI2008]火星人

用平衡树维护字符串的hash

然后询问的时候二分一下就好了

 /* http://www.cnblogs.com/karl07/ */
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define ull unsigned long long const int N=;
const int P=;
struct tre{
int key,sz,t;
ull hash;
tre *ls,*rs;
}t[N*],*NEW=t,*null=t,*root,*r1,*r2,*r3;
ull base[N];
char s[N];
int n; inline tre *new1(int x){
NEW++;
NEW->t=x;
NEW->key=rand();
NEW->sz=;
NEW->hash=x;
NEW->ls=NEW->rs=null;
return NEW;
} inline void update(tre *p){
p->sz=p->ls->sz++p->rs->sz;
p->hash=p->ls->hash*base[p->rs->sz+]+p->t*base[p->rs->sz]+p->rs->hash;
} void merge(tre *&p,tre *x,tre *y){
if (x==null) { p=y; return; }
if (y==null) { p=x; return; }
if (x->key>y->key){
p=x;
merge(p->rs,p->rs,y);
}else{
p=y;
merge(p->ls,x,p->ls);
}
update(p);
} void split(tre *p,tre *&x,tre *&y,int k){
if (k==) { x=null,y=p; return; }
if (k==p->sz) { y=null,x=p; return; }
if (k>=p->ls->sz+){
x=p;
split(p->rs,p->rs,y,k-p->ls->sz-);
}else{
y=p;
split(p->ls,x,p->ls,k);
}
update(p);
} void HASH(){
null->ls=null->rs=null;
null->hash=;
null->sz=null->t=;
null->key=-;
root=null;
base[]=;
for (int i=;i<N;i++) base[i]=base[i-]*P;
} inline ull Q(tre *p,int l,int x){
ull ans;
split(root,r1,r2,l-);
split(r2,r2,r3,x);
ans=r2->hash;
merge(r2,r2,r3);
merge(root,r1,r2);
return ans;
} inline void R(int l,int x){
split(root,r1,r2,l-);
split(r2,r2,r3,);
merge(r1,r1,new1(x));
merge(root,r1,r3);
} inline void I(int l,int x){
split(root,r1,r2,l);
merge(r1,r1,new1(x));
merge(root,r1,r2);
} inline int query(int x,int y){
if (x>y) swap(x,y);
int l=,r=root->sz-y+,ans=;
while (l<=r){
int mid=(l+r)/;
ull a1=Q(root,x,mid),a2=Q(root,y,mid);
if (a1==a2){
ans=mid;
l=mid+;
}else{
r=mid-;
}
}
return ans;
} int main(){
HASH();
scanf("%s",s);
scanf("%d",&n);
for (int i=,l=strlen(s);i<=l-;i++){
merge(root,root,new1(s[i]));
}
for (int i=,x,y;i<=n;i++){
char ss[],s1[];
scanf("%s",ss);
if (ss[]=='Q') { scanf("%d%d",&x,&y); printf("%d\n",query(x,y)); }
if (ss[]=='R') { scanf("%d%s",&x,s1); R(x,s1[]);}
if (ss[]=='I') { scanf("%d%s",&x,s1); I(x,s1[]);}
}
return ;
}

并不会splay。。只会非旋转treap。。10s正好卡过去。。药丸

上一篇:windows下用vs2008和boost结合编译程序


下一篇:第17讲- UI常用组件之ImageView图片浏览