zoukankan      html  css  js  c++  java
  • 【HDU5785】Interesting [Manacher]

    Interesting

    Time Limit: 30 Sec  Memory Limit: 256 MB
    [Submit
    ][Status][Discuss]

    Description

      

    Input

      

    Output

      

    Sample Input

      2
      aaa
      abc

    Sample Output

      14
      8

    HINT

      

    Source

      我们先找一下这道题的本质,根据乘法分配律,我们可以使得:cntL[i]表示以 i 开始的是回文串的下标和,cntR[i]表示以 i 结束的回文串的下标和,那么这时候答案显然就是cntR[i]×cntL[i+1]。

      我们再来思考一下怎么求出cntL和cntR,显然我们可以运用Manacher算法O(n)得到每一个回文半径,然后 i 对于cntL和cntR的影响显然就是一个序列上的等差数列。

      接着我们再记录一下del表示公差,O(n)推一下等差数列每个位置的和即可。

    Code

     1 #include<iostream>  
     2 #include<string>  
     3 #include<algorithm>  
     4 #include<cstdio>  
     5 #include<cstring>  
     6 #include<cstdlib>  
     7 #include<cmath>
     8 using namespace std;  
     9 typedef long long s64;
    10 
    11 const int ONE = (1e6+5)*2;
    12 const int MOD = 1e9+7;
    13 const int Niyu = 5e8+4;
    14 
    15 int T;
    16 int cntL[ONE],delL[ONE],l;
    17 int cntR[ONE],delR[ONE],r;
    18 char s[ONE],a[ONE];
    19 int p[ONE],n;
    20 int Ans;
    21 
    22 int get() 
    23 {
    24         int res=1,Q=1;  char c;
    25         while( (c=getchar())<48 || c>57)
    26         if(c=='-')Q=-1;
    27         if(Q) res=c-48; 
    28         while((c=getchar())>=48 && c<=57) 
    29         res=res*10+c-48; 
    30         return res*Q; 
    31 }
    32 
    33 void Deal_first()
    34 {
    35         a[0] = '(';
    36         for(int i=1;i<=n;i++)
    37         {
    38             a[2*i-1] = '#';
    39             a[2*i] = s[i];
    40         }
    41         n = 2 * n + 1;
    42         a[n] = '#';    a[n+1] = ')';
    43 }
    44 
    45 void Manacher()
    46 {
    47         int l = 0, id = 0;
    48         for(int i=1;i<=n;i++) p[i] = 0;
    49         for(int i=1;i<=n;i++)
    50         {
    51             if(l >= i) p[i] = min(p[id + id - i], l - i);
    52             else p[i] = 1;
    53             while(a[i-p[i]] == a[i+p[i]]) p[i]++;
    54             if(p[i] + i > l) l = p[i]+i, id = i;
    55         }
    56 }
    57 
    58 void Add(int &a,int b) {a+=b;    if(a>0) a-=MOD;    if(a<0) a+=MOD;}
    59 
    60 void Solve()
    61 {
    62         scanf("%s",s+1);    n=strlen(s+1);
    63         Deal_first();    Manacher();
    64         
    65         for(int i=1;i<=n;i++) cntL[i]=cntR[i]=delL[i]=delR[i]=0;
    66         
    67         for(int i=1;i<=n;i++)
    68         {
    69             l = i-p[i]+1;    r = i+p[i]-1;
    70             Add(cntL[l], r);    Add(cntL[i+1], -r+(i-l));    Add(delL[l+1], -1);    Add(delL[i+1], 1);
    71             Add(cntR[i], i);    Add(cntR[r+1], -i+(r-i));    Add(delR[i+1], -1);    Add(delR[r+1], 1);
    72         }
    73         
    74         for(int i=1;i<=n;i++)
    75         {
    76             Add(cntL[i],cntL[i-1]);    Add(delL[i],delL[i-1]);    Add(cntL[i],delL[i]);
    77             Add(cntR[i],cntR[i-1]);    Add(delR[i],delR[i-1]);    Add(cntR[i],delR[i]);
    78         }
    79         
    80         n=strlen(s+1);
    81         Ans = 0;
    82         for(int i=1;i<n;i++)
    83         {
    84             Ans = Ans + (s64)cntR[2*i] *Niyu%MOD * cntL[2*(i+1)]%MOD *Niyu%MOD ;
    85             Add(Ans,0);
    86         }
    87         
    88         printf("%d
    ",Ans);
    89 }
    90 
    91 int main()
    92 {
    93         T=get();
    94         while(T--)
    95             Solve();
    96 }
    View Code
  • 相关阅读:
    Saltstack module gem 详解
    Saltstack module freezer 详解
    Saltstack module firewalld 详解
    Saltstack module file 详解
    Saltstack module event 详解
    Saltstack module etcd 详解
    Saltstack module environ 详解
    Saltstack module drbd 详解
    Saltstack module dnsutil 详解
    获取主页_剥离百度
  • 原文地址:https://www.cnblogs.com/BearChild/p/6571040.html
Copyright © 2011-2022 走看看