• Tsinsen Palisection


    建回文树。

    正反建统计一种前缀和求出所有不相交的,用总数减去就是答案数。

    在这里我们可以知道一个字符串中所有回文串的个数即为num数组之和(因为以一个节点为回文串结尾的字串都是唯一的)

    也可以是cnt数组的和(想想看为什么)

    题目链接:http://www.tsinsen.com/ViewGProblem.page?gpid=A1393

    来源是Codeforces17E,但这样会MLE所以可以使用Vector替代next数组(时间换空间)这里不给出代码。

    By:大奕哥

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=2e6+10;
     4 const int mod=51123987;
     5 const int M=26;
     6 struct node
     7 {
     8     int num[N],cnt[N],nex[N][M],fail[N],S[N],len[N];
     9     int n,p,last;
    10     int newnode(int l)
    11     {
    12         for(int i=0;i<M;++i)nex[p][i]=0;
    13         cnt[p]=num[p]=0;
    14         len[p]=l;
    15         return p++;
    16     }
    17     
    18     void init()
    19     {
    20         p=0;n=1;
    21         newnode(0);newnode(-1);
    22         last=n=0;
    23         S[n]=-1;fail[0]=1;
    24     }
    25     
    26     int getfail(int x)
    27     {
    28         while(S[n-len[x]-1]!=S[n])x=fail[x];
    29         return x;
    30     }
    31     
    32     int add(int c)
    33     {
    34         c=c-'a';
    35         S[++n]=c;
    36         int cur=getfail(last);
    37         if(!nex[cur][c])
    38         {
    39             int now=newnode(len[cur]+2);
    40             fail[now]=nex[getfail(fail[cur])][c];
    41             nex[cur][c]=now;
    42             num[now]=num[fail[now]]+1;
    43         }
    44         last=nex[cur][c];
    45         cnt[last]++46         return num[last];
    47     }
    48     void count()
    49     {
    50         for(int i=p-1;i>=1;--i)cnt[fail[i]]+=cnt[i];
    51     }
    52 }T;
    53 char s[N];
    54 int ll[N],rr[N];
    55 int main()
    56 {
    57     int n;long long sum=0,ans=0;
    58     scanf("%d%s",&n,s);
    59     T.init();
    60     for(int i=n-1;i>=0;--i)
    61     {
    62         ll[i]=(T.add(s[i])+ll[i+1])%mod;
    63     }
    64     T.init();
    65     for(int i=0;i<n;++i)
    66     {
    67         rr[i]=T.add(s[i]);sum+=rr[i];sum%=mod;
    68         ans=(ans+1ll*ll[i+1]*rr[i]%mod)%mod;
    69     }
    70     ans=(1ll*sum*(sum-1)/2%mod-ans+mod)%mod;
    71     printf("%lld
    ",ans);
    72     return 0;
    73 }

    Ps:随时注意取模。。。

  • 相关阅读:
    基础之实战猜年龄游戏
    基本运算符与if while详解:
    while循环练习:
    常量与格式化输出练习
    Flask基础(05)-->路由的基本定义
    Flask基础(04)-->相关配置参数
    Flask基础(03)-->创建第一个Flask程序
    Flask基础(02)-->搭建Flask项目虚拟环境
    Flask基础(01)-->Flask框架介绍
    Flask实战第61天:帖子板块过滤显示
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8260972.html
Copyright © 2020-2023  润新知