zoukankan      html  css  js  c++  java
  • bzoj5137 [Usaco2017 Dec]Standing Out from the Herd

    link

    题意:

    给你n个串,对于每个串求出只包含在这个串中的本质不同子串数量。

    $n,sum |S| leq 10^5.$

    题解:

    广义sam,right集合定义为多个串中出现的位置的并。

    某个子串只出现在一个串中等价于当前状态的right集合只属于一个串。令f[u]表示u状态的right集合属于哪个串,若属于多个串记为-1,建出树以后自下而上合并right即可。

    复杂度$mathcal{O}(n)$。

    code:

     1 #include<bits/stdc++.h>
     2 #define rep(i,x,y) for (int i=(x);i<=(y);i++)
     3 #define ll long long
     4 #define inf 1000000001
     5 #define y1 y1___
     6 using namespace std;
     7 char gc(){
     8     static char buf[100000],*p1=buf,*p2=buf;
     9     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    10 }
    11 #define gc getchar
    12 ll read(){
    13     char ch=gc();ll x=0;int op=1;
    14     for (;!isdigit(ch);ch=gc()) if (ch=='-') op=-1;
    15     for (;isdigit(ch);ch=gc()) x=(x<<1)+(x<<3)+ch-'0';
    16     return x*op;
    17 }
    18 #define N 200005
    19 int n,tot=1,rt=1,last=1,fa[N],ch[N][30],len[N],f[N],head[N],cnt,ans[N];char str[N];
    20 struct edge{int to,nxt;}e[N];
    21 void adde(int x,int y){
    22     e[++cnt].to=y;e[cnt].nxt=head[x];head[x]=cnt;
    23 }
    24 void extend(int c,int id){//广义sam,right集合定义为多个串中出现的位置的并
    25     int p=last,np=last=++tot,q,nq;len[np]=len[p]+1;
    26     for (;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
    27     if (!p) fa[np]=rt;
    28     else{
    29         q=ch[p][c];
    30         if (len[q]==len[p]+1) fa[np]=q;
    31         else{
    32             nq=++tot;len[nq]=len[p]+1;
    33             memcpy(ch[nq],ch[q],sizeof(ch[q]));
    34             fa[nq]=fa[q];fa[np]=fa[q]=nq;
    35             for (;p&&ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
    36         }
    37     }
    38     if (f[np]&&f[np]!=id) f[np]=-1;else f[np]=id;
    39 }
    40 void dfs(int u){
    41     for (int i=head[u];i;i=e[i].nxt) dfs(e[i].to);
    42     if (f[u]&&f[u]!=-1) ans[f[u]]+=len[u]-len[fa[u]];
    43     if (f[fa[u]]&&f[fa[u]]!=f[u]) f[fa[u]]=-1;else f[fa[u]]=f[u];
    44 }
    45 int main(){
    46     n=read();
    47     rep (i,1,n){
    48         scanf("%s",str+1);int l=strlen(str+1);
    49         last=rt;
    50         rep (j,1,l) extend(str[j]-'a',i);
    51     }
    52     rep (i,2,tot) adde(fa[i],i);
    53     dfs(rt);
    54     rep (i,1,n) printf("%d
    ",ans[i]);
    55     return 0;
    56 }
    View Code
  • 相关阅读:
    #ifndef 、 #define 、#endif使用解释
    基于小熊派Hi3861鸿蒙开发的IoT物联网学习【六】--智慧农业MQTT数据上传华为云
    C语言学习(三)
    c语言学习篇二【基础语法】
    简单图解OSI七层网络模型
    基于小熊派Hi3861鸿蒙开发的IoT物联网学习【五】
    使用Doxygen生成html/chm范例,方便源码阅读
    李宏毅《深度学习》P1----机器学习介绍
    keras实现Alexnet (cifar10数据集)
    cmake条件编译
  • 原文地址:https://www.cnblogs.com/bestFy/p/9386410.html
Copyright © 2011-2022 走看看