zoukankan      html  css  js  c++  java
  • CF17E Palisection (回文自动机+DP)

    题目传送门

    题目大意:给你一个字符串,让你求出有多少对相交的回文子串

    啊啊啊啊降智了,我怎么又忘了正难则反

    求相交会很难搞。把问题转化成求互不相交的回文子串再减一下就行了

    先利用$PAM$求出以每个位置为末尾的回文子串数量,这个数量就是此时构造末尾节点在$fail$树中的深度

    再把串翻过来,用同样的方法求出每个位置为开头的回文子串数量

    对其中一个数组求前缀和,用乘法原理算一下就行了

    空间开不下怎么办?以时间换空间,用邻接表存儿子!每次跳儿子都暴力遍历一次邻接表

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define ll long long
     5 #define N1 2000010 
     6 using namespace std;
     7 const int p=51123987;
     8 
     9 template <typename _T> void read(_T &ret)
    10 {
    11     ret=0; _T fh=1; char c=getchar();
    12     while(c<'0'&&c>'9'){ if(c=='-') fh=-1; c=getchar(); }
    13     while(c>='0'&&c<='9'){ ret=ret*10+c-'0'; c=getchar(); }
    14     ret=ret*fh;
    15 }
    16 /*void exgcd(ll a,ll b,ll &x,ll &y)
    17 {
    18     if(!b){ x=1; y=0; return; }
    19     exgcd(b,a%b,x,y); ll t=x; x=y; y=t-a/b*y;
    20 }*/
    21 
    22 int idx(char c){ return c-'a'; }
    23 
    24 struct Edge{
    25 int to[N1],nxt[N1],val[N1],head[N1],cte;
    26 void ae(int u,int v,int w)
    27 { cte++; to[cte]=v; nxt[cte]=head[u]; val[cte]=w; head[u]=cte; }
    28 }e;
    29 
    30 namespace PAM{
    31 int pre[N1],dep[N1],sum[N1],sz[N1],la,tot;
    32 void clr()
    33 {
    34     memset(pre,0,sizeof(pre)); memset(dep,0,sizeof(dep)); 
    35     memset(sum,0,sizeof(sum)); memset(&e,0,sizeof(e));
    36 }
    37 void init(){ la=tot=1; pre[0]=pre[1]=1; dep[1]=-1; }
    38 int same(char *str,int p,int i){ return str[i-dep[p]-1]==str[i]; }
    39 int trs(int x,int c)
    40 { 
    41     for(int j=e.head[x];j;j=e.nxt[j])
    42         if(e.val[j]==c) return e.to[j];
    43     return 0; 
    44 }
    45 int insert(char *str,int i)
    46 {
    47     int p=la,np,fp,tp,c=idx(str[i]);
    48     while(!same(str,p,i)) p=pre[p];
    49     if(!(tp=trs(p,c))) //!trs[p][c]
    50     {
    51         np=++tot; 
    52         dep[np]=dep[p]+2; 
    53         fp=pre[p];
    54         while(!same(str,fp,i)) fp=pre[fp];
    55         pre[np]=trs(fp,c); //trs[fp][c]
    56         e.ae(p,np,c); //trs[p][c]=np;
    57         p=np;
    58     }else p=tp;
    59     la=p; 
    60     sum[p]=sum[pre[p]]+1;
    61     return p;
    62 }
    63 };
    64 
    65 int n;
    66 char str[N1];
    67 ll lsum[N1],rsum[N1];
    68 
    69 int main()
    70 {
    71     int i,j,x; ll ans=0;
    72     scanf("%d",&n);
    73     scanf("%s",str+1);
    74     PAM::init();
    75     for(i=1;i<=n;i++) x=PAM::insert(str,i), lsum[i]=PAM::sum[x];// ans+=lsum[i];
    76     PAM::clr(); PAM::init();
    77     reverse(str+1,str+n+1);
    78     for(i=1;i<=n;i++) x=PAM::insert(str,i), rsum[i]=PAM::sum[x], rsum[i]+=rsum[i-1]; //rsum[i]+=rsum[i-1];
    79     if(rsum[n]&1) ans=1ll*((rsum[n]-1)/2%p)*(rsum[n]%p)%p;
    80     else ans=1ll*(rsum[n]/2%p)*((rsum[n]-1)%p)%p;
    81     for(i=2;i<=n;i++) ans=(ans-1ll*lsum[i-1]*rsum[n-i+1]%p+p)%p;
    82     printf("%I64d
    ",(ans%p+p)%p);
    83     return 0;
    84 }
  • 相关阅读:
    浅谈 Linux 下的 SSH1, SSH2
    jquery replace方法去空格
    CakePHP Configure::read('KHCITY') 数据配置读取
    php中::是什么意思?
    CakePHP redirect函数
    Redis介绍
    Microsoft Dynamics CRM 2011 面向Internet部署 (IFD) ADFS虚拟机环境搭建的步骤(CRM与ADFS装在同一台服务器上) 摘自网络
    [Windows Server] 在 Windows Server 2012 上安裝 .NET Framework 3.5
    Solution for When browse http://xxx/ReportServer Show Error (rsAccessDenied)
    Windows Server 2008 R2 配置AD(Active Directory)域控制器 -zhai zi wangluo
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10639731.html
Copyright © 2011-2022 走看看