acdream 1019: Palindrome 字符串多项式取Hash值

1019: Palindrome

Time Limit: 1 Sec  Memory Limit: 128 MB 

Description

Now we have a long long string, and we will have two kinds of operation on it.
C i y: change the ith letter to y;
Q i j: check whether the substring from ith letter to jth letter is a palindrome.
 
 

 

Input

There are multiple test cases.
The first line contains a string whose length is not large than 1,000,000.
The next line contains a integer N indicating the number of operations.
The next N lines each lines contains a operation.
All letters in the input are lower-case.

 

Output

For each query operation, output "yes" if the corresponding substring is a palindrome, otherwise output "no".

 

Sample Input

aaaaa 4 Q 1 5 C 2 b Q 1 5 Q 1 3

Sample Output

yes no yes

HINT

 

Source

Adapted from a problem by yy17yy, 3x......
 
题目大意: 输入一个10^6长字符串,然后M种操作,Q(i,j)为查询(i,j)的字串是否为回文串,C(i,ch)为将i位置字符改为ch。
 
解题思路:若字符串为回文串,则其正序的hash值与其逆序的hash值相同。在这里我们使用多项式差值取模来求子串hash值,因为字符可限定为[1,26],所以基数设定为27。
 
假设字符串为(a1,a2,a3,a4,..,an)  其hash编码为 a1*pow(27,0)+a2*pow(27,1)+..+an*pow(27,n-1) , 例如2进制表示一个序列,若不相等必定不会出现重复hash值。一样的原理。理论上如此,但是这里pow(27,10^6) 数值太大,必定溢出,为何不会出错我估计是数据不够大吧~~~
 
通过hash值来简化字符串回文判定问题。使用树状数组来处理修改和数组和相加问题。时间复杂度O(m*log(n))
 
View Code
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<math.h>
 5 #include<iostream>
 6 using namespace std;
 7 
 8 typedef unsigned long long LL;
 9 const int N = 1000007;
10 
11 LL bit[N], C[2][N];
12 int n, m;
13 char str[N];
14 void update( int x, LL val, int flag )
15 {
16     for( ; x <= n; x += x&(-x) )
17         C[flag][x] += val;
18 }
19 LL sum( int x, int flag )
20 {
21     LL res = 0;
22     for( ; x >= 1; x -= x&(-x) )
23         res += C[flag][x];
24     return res;
25 }
26 void InitBit(){
27     bit[0] = 1;
28     for(int i = 1; i < N; i++)
29         bit[i] = bit[i-1]*27;
30 }
31 void init(){
32     n = strlen( str );
33     memset( C, 0, sizeof(C) );
34     for(int i = 1; i <= n; i++)
35     {
36         int j = (n+1)-i;    
37         update( i, (str[i-1]-'a'+1)*bit[i-1], 0 );
38         update( j, (str[i-1]-'a'+1)*bit[j-1], 1 ); 
39     }
40 }
41  
42 void solve(){
43     scanf("%d", &m);
44     char op[2], ch[2]; 
45     int a, b, c, d;
46     while( m-- )
47     {
48         scanf("%s", op);
49         if( op[0] == 'Q' )
50         {
51             scanf("%d%d",&a,&b);
52             if(a > b) swap(a,b);    
53             d = (n+1)-a; c = (n+1)-b;
54             LL hash0 = ( sum(b,0)-sum(a-1,0) )*bit[c-1];//对阶    
55             LL hash1 = ( sum(d,1)-sum(c-1,1) )*bit[a-1];    
56             puts( hash0 == hash1 ? "yes" : "no" );    
57         }
58         else
59         {
60             scanf("%d%s",&a,ch);
61             b = (n+1)-a;
62             update( a, (ch[0]-str[a-1])*bit[a-1], 0 );
63             update( b, (ch[0]-str[a-1])*bit[b-1], 1 );
64             str[a-1] = ch[0];    
65         }
66     }
67 }
68 int main(){
69     InitBit();    
70     while( scanf("%s",str) != EOF)
71     {
72         init();
73         solve();
74     }
75     return 0;
76 }

 

 
 
posted @ 2012-12-08 17:12  yefeng1627  阅读(244)  评论(0编辑  收藏  举报

Launch CodeCogs Equation Editor