acdream1104 瑶瑶想找回文串
来源:互联网 发布:写漫画的软件 编辑:程序博客网 时间:2024/06/05 07:32
瑶瑶想找回文串
Time Limit: 20000/10000MS (Java/Others)Memory Limit: 256000/128000KB (Java/Others)
SubmitStatisticNext Problem
Problem Description
刚学完后缀数组求回文串的瑶瑶(tsyao)想到了另一个问题:如果能够对字符串做一些修改,怎么在每次询问时知道以某个字符为中心的最长回文串长度呢?因为瑶瑶整天只知道LOL,当他知道自己省选成绩的时候就天天在LOL,导致现在的她实在是太弱了,根本解决不了这个问题,于是就来找你帮忙,么么哒~你就帮帮她吗
Input
第一行为一个长度不超过100000字符串s作为初始字符串。第二行一个正整数n,表示操作/询问的个数。接下来n行,每行有如下几种可能出现的操作/询问:
Insert a x 在a处字符的后面插入一个字符x
Delete a 把a处字符删除
Update a x 把a处字符改为x
Query a 查询以a为中心的最长回文串长度
Output
对于每个询问,输出得到的最长回文串长度
Sample Input
baaaaab5Query 4Delete 2Query 3Delete 4Query 3
Sample Output
735
Hint
对于100%的数据 1<=n<=50000,字符串仅包含小写字母,保证操作过程中字符串长度不超过150000 (hint:请各位大胆写)
单组输入,共10组数据。
Source
zslzx
Manager
tsyao
二分+字符串哈希+splay;
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<queue>#include<ctime>#include<map>#include<set>#include<stack>#include<list>#define maxn 200010#define LL long long#define u64 unsigned long long#define yy 133using namespace std ;int num[maxn];u64 bit[maxn];struct node { int size ; int ch[2]; int pra; u64 lsum,rsum,val; void init( int tt ) { ch[0] = ch[1] = 0; size = 1; lsum = rsum = val = tt ; }} tree[maxn];int len;int root;char a[maxn];int n, m;int getSize(int x) { if (x) return tree[x].size; return 0;}u64 getlsum( int x ){ if(x) return tree[x].lsum ; return 0 ;}u64 getrsum( int x ){ if(x) return tree[x].rsum ; return 0 ;}void update(int x) { tree[x].size = 1 + getSize(tree[x].ch[0]) + getSize(tree[x].ch[1]); tree[x].lsum = tree[x].val*bit[getSize(tree[x].ch[0])] + getlsum(tree[x].ch[0]) +getlsum(tree[x].ch[1])*bit[getSize(tree[x].ch[0])+1] ; tree[x].rsum = tree[x].val*bit[getSize(tree[x].ch[1])] + getrsum(tree[x].ch[1]) +getrsum(tree[x].ch[0])*bit[getSize(tree[x].ch[1])+1] ;}void build( int &x , int s , int e , int f ){ if(s>e) return ; int mid = (s+e)>>1 ; x = ++len ; tree[x].pra = f ; tree[x].init(num[mid]) ; build(tree[x].ch[0],s,mid-1,x) ; build(tree[x].ch[1],mid+1,e,x) ; update(x) ;}void init(){ int i , k , l ; len = 0 ; tree[0].pra = -1 ; tree[0].init(-1) ; for( i = 1 ; i <= n ;i++){ num[i] = a[i-1]-'a'+1; } num[0] = num[n+1] = -1 ; build( tree[0].ch[1] , 0 , n+1 , 0 ) ;}void rotate(int x , int d ){ int p = tree[x].pra ; tree[p].ch[d] = tree[x].ch[d^1] ; tree[tree[x].ch[d^1]].pra = p ; tree[x].ch[d^1] = p ; int g = tree[p].pra ; tree[p].pra = x ; if( g != -1 ) tree[g].ch[p == tree[g].ch[1]] = x ; tree[x].pra = g ; //更新值 tree[x].size = tree[p].size ; update(p) ; return ;}void splay( int &x , int f ){ while( tree[x].pra != f ) { int p = tree[x].pra ; if(tree[p].pra == f ) { if( tree[p].ch[0] == x ) rotate(x,0) ; else rotate(x,1) ; } else { int g = tree[p].pra ; if( tree[g].ch[0] == p ) { if( tree[p].ch[0] == x ) rotate(p,0),rotate(x,0) ; else rotate(x,1),rotate(x,0) ; } else{ if( tree[p].ch[1] == x ) rotate(p,1),rotate(x,1) ; else rotate(x,0),rotate(x,1) ; } } } update(x) ;}void select( int k , int f ){ int x = tree[0].ch[1] ; while( k != getSize(tree[x].ch[0])+1) { if( k <= getSize(tree[x].ch[0])) { x = tree[x].ch[0] ; } else { k -= 1+getSize(tree[x].ch[0]) ; x = tree[x].ch[1] ; } } splay(x,f) ;}void cut(){ int a, b , c , i ; scanf("%d" , &a) ; b = a ; select(a,0) ; root = tree[0].ch[1] ; select(b+2,root) ; int tmp = tree[tree[root].ch[1]].ch[0] ; n-- ; tree[tree[root].ch[1]].ch[0] = 0 ; update(tree[root].ch[1]) ; update(root) ;}void replace(){ int a, b , i ; char c[2]; scanf("%d%s" , &a,c ) ; b = a ; select(a,0) ; root = tree[0].ch[1] ; select(b+2,root) ; int tmp = tree[tree[root].ch[1]].ch[0] ; tree[tmp].init(c[0]-'a'+1) ; update(tree[root].ch[1]) ; update(root) ;}void insert(){ int a, b , i ; char c[2]; scanf("%d%s" , &a,c ) ; select(a+1,0) ; root = tree[0].ch[1] ; select(a+2,root) ; n++; int tmp = ++len ; tree[tmp].init(c[0]-'a'+1) ; tree[tree[root].ch[1]].ch[0] = tmp ; tree[tmp].pra = tree[root].ch[1] ; update(tree[root].ch[1]) ; update(root) ;}bool check(int k,int mid){ select(k-mid,0) ; root = tree[0].ch[1] ; select(k+mid+2,root) ; int tmp = tree[tree[root].ch[1]].ch[0] ; return tree[tmp].lsum == tree[tmp].rsum ;}int main(){ int i,k ; int L,R,mid,ans; u64 u,v; char str[20] ; bit[0]=1; for( i = 1 ; i < maxn-10 ;i++) bit[i]=bit[i-1]*yy; while(scanf("%s",a) != EOF) { n = strlen(a) ; init(); scanf("%d",&m) ; while(m--) { scanf("%s",str) ; if(str[0]=='I') { insert(); } else if(str[0]=='D') { cut(); } else if(str[0]=='U') { replace(); } else{ ans=0; scanf("%d",&k); L=0;R=min(k-1,n-k); while(L<R) { mid=(L+R+1)>>1 ; if(check(k,mid)) { ans=mid; L=mid; } else R = mid-1; } printf("%d\n",ans*2+1); } } } return 0 ;}
0 0
- acdream1104 瑶瑶想找回文串
- 回文数&&回文串
- 回文串
- 回文串
- 回文串
- 回文串
- 回文串
- 回文串
- 回文串
- 回文串
- 回文串
- 回文串
- 回文串
- **回文串
- 回文串
- 回文串
- 回文串
- 回文串
- jersey上传图片
- 功有所在 責有所歸
- Android之ORM,IOC,HTTP工具框架
- Window 下 android 开发的环境搭建
- ReorderList-- 链表重现排序
- acdream1104 瑶瑶想找回文串
- ajax load
- 安装OpenResty
- [WebGL入门]十七,递归处理和移动・旋转・缩放
- dojo中获取表格中某一行的某个值
- Android 通过GET和POST方式提交参数给web应用
- 人民币数字金额转大写金额
- HDU 1233 还是畅通工程
- HDU 4937 Lucky Number