zoukankan      html  css  js  c++  java
  • 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:随时注意取模。。。

  • 相关阅读:
    Python 中的 __str__ 与 __repr__ 到底有什么差别
    02 LeetCode---链表相加
    01 LeetCode---两数之和
    python 数据结构一 之 线性表
    来自C++的"Const式"傲娇
    string 与 char 字符串区别-1
    超级有爱的并查集入门
    多项式求解
    竞码编程-蓝桥杯模拟赛4-D题
    树的直径-蓝桥杯大臣的旅费
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8260972.html
Copyright © 2011-2022 走看看