[noi34]palindrome

Segmentation is actually continuously withdrawn from both ends of the same period, and the remaining string is divided. Let's prove it every greedy out the shortest period of validity:

Consider two division method, denoted as S = A + B + A and + C = D + S C , where A is the shortest period, then when 2 | A | <| C | , there apparently C = A + a + E , then it can be divided by three times to complete C , and when | a | <| C | <2 | a | , i.e., a at C overlap, then the shortest prefix must not a , but the overlapping portion ( both overlapping portion a prefix is a suffix).

Then the greedy to set up, use hash judge to violence.

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define mod 1000000007
 4 #define ll long long
 5 #define N 1000001
 6 int t,l;
 7 ll sum[N],mi[N];
 8 char s[N];
 9 ll calc(int l,int r){
10      return ((sum[r]-sum[l-1]*mi[r-l+1])%mod+mod)%mod;
11 }
12 int work(int l,int r){
13     if (l>r)return 0;
14     int mid=(l+r+1>>1),k=l;
15     while ((k<mid)&&(calc(l,k)!=calc(l+r-k,r)))k++;
16     if (k==mid)return 1;
17     return work(k+1,l+r-k-1)+2;
18 }
19 int main(){
20      mi[0]=1;
21      for(int i=1;i<N;i++)mi[i]=(mi[i-1]*29)%mod;
22      scanf("%d",&t);
23      while (t--){
24           scanf("%s",s);
25           l=strlen(s);
26           sum[0]=s[0]-'a'+1;
27           for(int i=1;i<l;i++)sum[i]=(sum[i-1]*29+s[i]-'a'+1)%mod;
28           printf("%d\n",work(0,l-1));
29      }
30 }
View Code

 

Guess you like

Origin www.cnblogs.com/PYWBKTDA/p/11272226.html