zoukankan      html  css  js  c++  java
  • [USACO17DEC]Standing Out from the Herd(广义后缀自动机)

    题意

    定义一个字符串的「独特值」为只属于该字符串的本质不同的非空子串的个数。如 "amy" 与 “tommy” 两个串,只属于 "amy" 的本质不同的子串为 "a" "am" "amy" 共 3 个。只属于 "tommy" 的本质不同的子串为 "t" "to" "tom" "tomm" "tommy" "o" "om" "omm" "ommy" "mm" "mmy" 共 11 个。 所以 "amy" 的「独特值」为 3 ,"tommy" 的「独特值」为 11 。

    给定 N ( N10^5 )  个字符集为小写英文字母的字符串,所有字符串的长度和小于 10^5 ,求出每个字符串「独特值」。

    题解

      这题和喵星人的点名那题有点像啊……会了那题做这题挺简单的

      先把所有串一起建一个广义SAM,然后把所有串放上去跑一遍,记录一下每一个子串属于多少个原串。然后再把所有串放上去跑一边,如果这个子串只属于一个原串,那么就把它的答案加上$l[i]-l[fa[i]]$(都是后缀自动机上的节点) 

     1 // luogu-judger-enable-o2
     2 //minamoto
     3 #include<cstring>
     4 #include<cstdio>
     5 using namespace std;
     6 char sr[1<<21],z[20];int C=-1,Z;
     7 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
     8 inline void print(int x){
     9     if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
    10     while(z[++Z]=x%10+48,x/=10);
    11     while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
    12 }
    13 const int N=1e5+5;
    14 char c[N];int len[N],tot,ans[N],s[N];
    15 int fa[N<<1],ch[N<<1][26],l[N<<1],sz[N<<1],las[N<<1];
    16 int n,cnt=1,last=1;
    17 void ins(int c){
    18     int p=last,np=++cnt;last=np,l[np]=l[p]+1;
    19     for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
    20     if(!p) fa[np]=1;
    21     else{
    22         int q=ch[p][c];
    23         if(l[p]+1==l[q]) fa[np]=q;
    24         else{
    25             int nq=++cnt;l[nq]=l[p]+1;
    26             memcpy(ch[nq],ch[q],sizeof(ch[q]));
    27             fa[nq]=fa[q];fa[q]=fa[np]=nq;
    28             for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
    29         }
    30     }
    31 }
    32 void update(int x,int y){
    33     for(;x&&las[x]!=y;x=fa[x])
    34     ++sz[x],las[x]=y;
    35 }
    36 void query(int x,int y){
    37     for(;x&&las[x]!=y;x=fa[x]){
    38         if(sz[x]==1) ans[y]+=l[x]-l[fa[x]];
    39         las[x]=y;
    40     }
    41 }
    42 int main(){
    43     scanf("%d",&n);
    44     for(int i=1;i<=n;++i){
    45         scanf("%s",c+1);
    46         len[i]=strlen(c+1);
    47         last=1;
    48         for(int j=1;j<=len[i];++j) s[++tot]=c[j]-'a',ins(s[tot]);
    49     }
    50     tot=0;
    51     for(int i=1;i<=n;++i)
    52     for(int j=1,x=1;j<=len[i];++j)
    53     update(x=ch[x][s[++tot]],i);
    54     for(int i=1;i<=cnt;++i) las[i]=0;
    55     tot=0;
    56     for(int i=1;i<=n;++i)
    57     for(int j=1,x=1;j<=len[i];++j)
    58     query(x=ch[x][s[++tot]],i);
    59     for(int i=1;i<=n;++i) print(ans[i]);
    60     Ot();
    61     return 0;
    62 }
  • 相关阅读:
    Hadoop_33_Hadoop HA的搭建
    Hadoop_32_HDFS高可用机制
    Hadoop_31_MapReduce参数优化
    Hadoop_30_MapReduce_多job串联
    Hadoop_29_MapReduce_计数器应用
    Hadoop_28_MapReduce_自定义 inputFormat
    Hadoop_27_MapReduce_运营商原始日志增强(自定义OutputFormat)
    Hadoop_26_MapReduce_Reduce端使用GroupingComparator求同一订单中最大金额的订单
    Hadoop_25_MapReduce实现日志清洗程序
    干货 | 剑指offer系列文章汇总
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9473445.html
Copyright © 2011-2022 走看看