1. 程式人生 > >LOJ6387 [THUPC2018] 綠綠與串串 【manacher】

LOJ6387 [THUPC2018] 綠綠與串串 【manacher】

pan set tin return sca size sizeof 分析 AR

題目分析:

比較簡單,先跑一邊manacher,然後對於回文部分可以碰到末尾的一定滿足條件,否則向後轉移。

代碼:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 1000020;
 5 
 6 char str[maxn],solve[maxn<<1];
 7 int f[maxn<<1],n;
 8 
 9 void manacher(){
10     memset(f,0,sizeof(f));
11     for(int i=2*n-2,j=n-1;i>=2
;i-=2,j--){ 12 solve[i] = str[j];solve[i-1] = $; 13 } 14 solve[0] = str[0]; 15 f[0] = 1; n = 2*n-1; 16 int fr = 0,last = 0; 17 for(int i=1;i<n;i++){ 18 if(last + fr >= i){ 19 if(last-(i-last)-f[last-(i-last)]+1 >= last- fr)f[i]=min(n-i,f[last-(i-last)]); 20 else
f[i] = min(n-i,last+fr-i+1); 21 while(i-f[i]>=0&&f[i]+i<n&&solve[f[i]+i]==solve[i-f[i]]) 22 f[i]++; 23 if(i+f[i]-1 >= last+fr) last = i,fr = f[i]-1; 24 }else{ 25 f[i] = 1; 26 while(i-f[i]>=0&&f[i]+i<n&&solve[f[i]+i]==solve[i-f[i]]) f[i]++;
27 last = i; fr = f[i]-1; 28 } 29 } 30 } 31 32 int ans[maxn]; 33 void work(){ 34 memset(ans,0,sizeof(ans)); 35 n = strlen(str);int trans = n; 36 manacher(); n = trans; 37 for(int i=n-1;i>=0;i--){ 38 int len = (f[i*2]+1)/2; 39 if(i + len == n) {ans[i] = 1;continue;} 40 if(i - len + 1 == 0){ans[i] = ans[i+len-1];continue;} 41 } 42 for(int i=0;i<n;i++) if(ans[i]) printf("%d ",i+1); 43 puts(""); 44 } 45 46 int main(){ 47 int t; scanf("%d",&t); 48 while(t--){ 49 scanf("%s",str); 50 work(); 51 } 52 return 0; 53 }

LOJ6387 [THUPC2018] 綠綠與串串 【manacher】