多校1005 HDU5785 Interesting (manacher)
1 // 多校1005 HDU5785 Interesting 2 // 题意:给你一个串,求相邻两个回文串左边端点*右边端点的和 3 // 思路:马拉车算出最长回文半径,求一个前缀和,既得到每个点对答案的贡献。 4 // ans=L[i]*R[i-1] 5 // L[i] 以i开始的所有回文串结尾坐标的和 6 // R[i] 以i结尾的所有回文串开始坐标的和 7 // 这题我们关键是求L[] R[] 8 // 另开两个数组a[] b[] 分别记录当前点对答案贡献 和每个点出现的次数 9 10 11 // #pragma comment(linker, "/STACK:102c000000,102c000000") 12 #include <iostream> 13 #include <cstdio> 14 #include <cstring> 15 #include <sstream> 16 #include <string> 17 #include <algorithm> 18 #include <list> 19 #include <map> 20 #include <vector> 21 #include <queue> 22 #include <stack> 23 #include <cmath> 24 #include <cstdlib> 25 // #include <conio.h> 26 using namespace std; 27 #define clc(a,b) memset(a,b,sizeof(a)) 28 #define inf 0x3f3f3f3f 29 #define lson l,mid,rt<<1 30 // #define rson mid+1,r,rt<<1|1 31 const int N = 1e6+10; 32 const int MOD = 1e9+7; 33 #define LL long long 34 #define LB long double 35 // #define mi() (l+r)>>1 36 double const pi = acos(-1); 37 const double eps = 1e-8; 38 void fre(){freopen("in.txt","r",stdin);} 39 inline int read(){int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9') { x=x*10+ch-'0';ch=getchar();}return x*f;} 40 41 char str[N]; 42 char s[N<<1]; 43 int Len[N<<1]; 44 void Manacher(int n){ 45 clc(s,'#'); 46 for(int i=0;i<n;i++) 47 s[i*2+2]=str[i]; 48 int len=n*2+1;s[0]='$'; 49 int mx=0,po=0; 50 for(int i=1;i<=len;i++) { 51 if(mx>i) 52 Len[i]=min(Len[po*2-i],mx-i); 53 else Len[i]=1; 54 while(s[i+Len[i]]==s[i-Len[i]]) Len[i]++; 55 if(i+Len[i]>mx) { mx=i+Len[i];po=i;} 56 } 57 } 58 59 LL a[N<<1],b[N<<1]; 60 LL L[N],R[N]; 61 int main(){ 62 while(~scanf("%s",str)){ 63 int len=strlen(str); 64 Manacher(len); 65 len=(len<<1)+1; 66 for(int i=0;i<=len;i++) a[i]=0,b[i]=0; 67 for(int i=len;i>=1;i--){ 68 a[i-Len[i]+1]+=i; 69 a[i+1]-=i; 70 b[i-Len[i]+1]++; 71 b[i+1]--; 72 } 73 LL a1=0,a2=0; 74 for(int i=1;i<=len;i++){ 75 a1+=a[i],a2+=b[i]; 76 if(i%2==0) 77 L[i/2]=(a1-a2*i/2)%MOD; 78 } 79 80 for(int i=0;i<=len;i++) a[i]=0,b[i]=0; 81 a1=0,a2=0; 82 for(int i=len;i>=1;i--){ 83 a[i]+=i; 84 a[i+Len[i]]-=i; 85 b[i]++; 86 b[i+Len[i]]--; 87 } 88 for(int i=1;i<=len;i++){ 89 a1+=a[i],a2+=b[i]; 90 if(i%2==0) 91 R[i/2]=(a1-a2*i/2)%MOD; 92 } 93 94 LL ans=0; 95 for(int i=2;i<=len/2;i++){ 96 ans=(ans+L[i]*R[i-1]%MOD)%MOD; 97 } 98 printf("%I64d\n",ans); 99 } 100 return 0; 101 }