多校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
",ans);
 99     }
100     return 0;
101 }
原文地址:https://www.cnblogs.com/ITUPC/p/5743973.html