[splay+二分+哈希] BZOJ1014: [JSOI2008]火星人prefix
来源:互联网 发布:淘宝如何拆分订单发货 编辑:程序博客网 时间:2024/05/16 19:44
题意
给出初始的字符串。需要进行M次操作描,操作有3种:
1.询问LCQ(x,y)。2.修改单个字符。3.插入单个字符。
其中LCQ(x,y)表示字符串x~len与y~len的最长公共前缀的长度。(len为当前串长)
M<=10^5
题解
对于静态的LCQ问题,我们可以对所有后缀排个序搞一搞实现,但是有了修改操作后就不行了,要另想办法。发现字符串的变化很自由,非常难控制,所以只好上大数据结构了,我们用splay维护序列,能解决修改问题。
但是询问操作如何实现呢?
splay并不能维护一些特别的信息,感觉很难办。注意到答案有二分性,是否能每次二分答案呢?要实现二分,需要快速比较两个长度相同的字符串是否相同。其实哈希一下就行了,实际效果是可以信赖的。哈希的值我们在splay中就可以维护了。
时间复杂度:
#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const LL MOD=1000000007;LL p[100005];struct node{ LL key,size,val; node *ch[2]; void maintain(){ size=ch[0]->size+ch[1]->size+1; val=(p[ch[1]->size+1]*ch[0]->val+key*p[ch[1]->size]+ch[1]->val)%MOD; } int cmp(int &k){ if(k<=ch[0]->size) return 0; if(k>ch[0]->size+1){ k-=ch[0]->size+1; return 1;} return -1; } } nil,base[200005],*null=&nil,*root,*t_len;typedef node* P_node;void Splay_init(){ null->size=null->val=0; null->ch[0]=null->ch[1]=null; t_len=base; }void rot(P_node &p,int d){ P_node k=p->ch[d^1]; p->ch[d^1]=k->ch[d]; k->ch[d]=p; p->maintain(); k->maintain(); p=k; }void splay(P_node &p,int k){ int d1=p->cmp(k); if(d1!=-1){ P_node p2=p->ch[d1]; int d2=p2->cmp(k); if(d2!=-1){ splay(p2->ch[d2],k); if(d1==d2) rot(p,d1^1), rot(p,d1^1); else rot(p->ch[d1],d2^1), rot(p,d1^1); } else rot(p,d1^1); }}P_node newnode(int tkey){ t_len->key=tkey; t_len->size=1; t_len->val=tkey; t_len->ch[0]=t_len->ch[1]=null; return t_len++;}char b[1000005];P_node build(int L,int R){ if(L>R) return null; int mid=(L+R)>>1; P_node p=newnode(b[mid]); p->ch[0]=build(L,mid-1); p->ch[1]=build(mid+1,R); p->maintain(); return p;}P_node merge(P_node left,P_node right){ splay(left,left->size); left->ch[1]=right; left->maintain(); return left;}void split(P_node p,int k,P_node &left,P_node &right){ splay(p,k); left=p; right=p->ch[1]; p->ch[1]=null; left->maintain();}bool check(int x,int y,int now){ P_node left,right; split(root,x-1,left,right); splay(right,now+1); int t1=right->ch[0]->val; root=merge(left,right); split(root,y-1,left,right); splay(right,now+1); int t2=right->ch[0]->val; root=merge(left,right); return t1==t2;}int Q;int main(){ freopen("bzoj1014.in","r",stdin); freopen("bzoj1014.out","w",stdout); Splay_init(); p[0]=1; for(int i=1;i<=100000;i++) p[i]=(p[i-1]*13)%MOD; scanf("%s",b+1); int len=strlen(b+1); b[0]='['; b[len+1]=']'; root=build(0,len+1); scanf("%d",&Q); while(Q--){ char ch[5]; scanf("%s",ch); if(ch[0]=='Q'){ int x,y; scanf("%d%d",&x,&y); x++; y++; int L=1,R=min(root->size-x,root->size-y),res=0; while(L<=R){ int mid=(L+R)>>1; if(check(x,y,mid)) L=mid+1,res=mid; else R=mid-1; } printf("%d\n",res); } if(ch[0]=='I'){ int x; scanf("%d",&x); x++; getchar();char ch=getchar(); P_node Left,Right; split(root,x,Left,Right); splay(Right,1); Right->ch[0]=newnode(ch); Right->maintain(); root=merge(Left,Right); } if(ch[0]=='R'){ int x; scanf("%d",&x); x++; getchar();char ch=getchar(); P_node Left,Right; split(root,x,Left,Right); splay(Left,Left->size-1); Left->ch[1]=newnode(ch); Left->maintain(); root=merge(Left,Right); } }}
0 0
- [splay+二分+哈希] BZOJ1014: [JSOI2008]火星人prefix
- 【bzoj1014】[JSOI2008]火星人prefix splay+hash+二分
- bzoj1014: [JSOI2008]火星人prefix splay
- [bzoj1014][splay][JSOI2008]火星人prefix
- [BZOJ1014] [JSOI2008] 火星人prefix - splay + hash + 二分答案
- [BZOJ1014][JSOI2008][Splay][RKHash]火星人prefix
- 【bzoj1014】【jsoi2008】【火星人prefix】【splay+hash】
- 【BZOJ1014】[JSOI2008]火星人prefix【Splay】【Hash】
- bzoj1014: [JSOI2008]火星人prefix(Splay)
- bzoj1014 [JSOI2008]火星人prefix ( splay + hash )
- 【BZOJ1014】[JSOI2008]火星人prefix
- [BZOJ1014] [JSOI2008]火星人prefix
- bzoj1014 [JSOI2008]火星人prefix
- bzoj1014: [JSOI2008]火星人prefix
- [BZOJ1014][JSOI2008]火星人prefix
- 【JSOI2008】【BZOJ1014】火星人prefix
- [BZOJ1014] [JSOI2008]火星人prefix
- bzoj1014: [JSOI2008]火星人prefix
- php 将价格改为千位,形式
- Android 模拟器启动异常
- 同一页面js传值到html
- word修改参考文献
- automaticallyAdjustsScrollViewInsets
- [splay+二分+哈希] BZOJ1014: [JSOI2008]火星人prefix
- Android-多媒体
- java 企业网站源码模版 有前后台 springmvc SSM 生成静态化
- 六十条有趣的经济学原则
- Jetty是什么?Jetty介绍以及配置
- LeetCode 520. Detect Capital
- js 模拟面向对象的方式
- Qt中建菜单栏和工具栏(泊松编辑)
- Sublime Text 3 快捷键总结