zoukankan      html  css  js  c++  java
  • BZOJ2946: [Poi2000]公共串

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2946

    先用第一个字符串建后缀自动机,每个节点记录一下每个字符串与之匹配的最大值,那么每个节点对答案的贡献就是所记录的最大值的最小值,把所有刚刚说的最小值取max就是答案了。绕晕了。语文不好真是日了狗。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #define inf 1<<30
     5 #define maxn 2005
     6 using namespace std;
     7 char s[maxn];
     8 int tot,last,root,sum,n,m,pps,v[maxn*2],q[maxn*2];
     9 struct fuck{int par,go[26],val,ans[6];}suf[maxn*2];
    10 int newnode(int x){suf[++tot].val=suf[x].val+1;return tot;}
    11 void extend(int x){
    12     int p=last,np=newnode(p);
    13     while(p&&suf[p].go[x]==0) suf[p].go[x]=np,p=suf[p].par;
    14     if(p==0) suf[np].par=root;
    15     else{
    16         int q=suf[p].go[x];
    17         if(suf[q].val==suf[p].val+1) suf[np].par=q;
    18         else{
    19             int nq=newnode(p);
    20             memcpy(suf[nq].go,suf[q].go,sizeof(suf[q].go));
    21             suf[nq].par=suf[q].par;
    22             suf[q].par=suf[np].par=nq;
    23             while(p&&suf[p].go[x]==q) suf[p].go[x]=nq,p=suf[p].par;
    24         }
    25     }
    26     last=np;
    27 }
    28 int main(){
    29     last=tot=root=1;
    30     scanf("%d
    ",&n); scanf("%s",s); m=strlen(s);
    31     for(int i=0;i<m;i++) extend(s[i]-'a');
    32     for(int i=1;i<=tot;i++) suf[i].ans[0]=suf[i].val;
    33     for(int i=1;i<=tot;i++) v[suf[i].val]++;
    34     for(int i=1;i<=tot;i++) v[i]+=v[i-1];
    35     for(int i=tot;i;i--) q[v[suf[i].val]--]=i;
    36     for(int j=2;j<=n;j++){
    37         scanf("%s",s); m=strlen(s); sum=0;
    38         for(int i=0,pp=root;i<m;i++){
    39             int f=s[i]-'a';
    40             while(pp&&!suf[pp].go[f]) pp=suf[pp].par;
    41             if(pp) sum=min(sum,suf[pp].val)+1,pp=suf[pp].go[f];
    42             else sum=0,pp=root;
    43             suf[pp].ans[j]=max(suf[pp].ans[j],sum);
    44         }
    45         for(int i=tot;i;i--) suf[suf[q[i]].par].ans[j]=max(suf[suf[q[i]].par].ans[j],suf[q[i]].ans[j]);
    46         for(int i=1;i<=tot;i++) suf[i].ans[0]=min(suf[i].ans[0],suf[i].ans[j]);
    47     }
    48     pps=0;
    49     for(int i=1;i<=tot;i++) pps=max(pps,suf[i].ans[0]);
    50     printf("%d
    ",pps);
    51     return 0;
    52 }
    View Code
  • 相关阅读:
    图论概况
    [NOI2006]最大获利
    Dining
    [USACO5.3]校园网Network of Schools 缩点
    I Hate It
    [USACO06JAN]牛的舞会The Cow Prom Tarjan
    爱在心中
    [HAOI2006]受欢迎的牛
    泥泞的道路
    上白泽慧音
  • 原文地址:https://www.cnblogs.com/longshengblog/p/5547358.html
Copyright © 2011-2022 走看看