zoukankan      html  css  js  c++  java
  • USACO 2017 December Contest Platinum T1: 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 (N1e5) 个字符集为小写英文字母的字符串,所有字符串的长度和小于 1e5,求出每个字符串「独特值」。

    题目分析

    看到这种有多个字符串的题,我们一般会去考虑使用广义SAM或把每个字符串连起来中间以特殊字符隔开。

    这里考虑广义SAM,其实就是每次加入新字符串时把lst置为1就行。

    我们对这些字符串建出广义SAM,每一个串都从根节点开始遍历,我们沿着ch数组往下跳,每到一个新节点时,再沿着parent树往上跳,这样可以保证遍历它的所有子串。

    最后统计一下只经过一次的节点 i 有哪些,把它的贡献 l[i]-l[fa[i]] 加给对应字符串即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int MAXN=2e5+10;
     5 
     6 int n,tot;
     7 int len[MAXN],s[MAXN];
     8 
     9 struct Suffix_Automation{
    10     int lst,cnt;
    11     int ch[MAXN][27],fa[MAXN],l[MAXN],vis[MAXN],ans[MAXN];
    12     Suffix_Automation(){lst=cnt=1;}
    13     inline void Extend(int x){
    14         int p=lst,np=++cnt;lst=np;
    15         l[np]=l[p]+1;
    16         while(p&&!ch[p][x]) ch[p][x]=np,p=fa[p];
    17         if(!p) fa[np]=1;
    18         else{
    19             int q=ch[p][x];
    20             if(l[q]==l[p]+1) fa[np]=q;
    21             else{
    22                 int nq=++cnt;
    23                 memcpy(ch[nq],ch[q],sizeof(ch[q]));
    24                 l[nq]=l[p]+1;
    25                 fa[nq]=fa[q];
    26                 fa[q]=fa[np]=nq;
    27                 while(ch[p][x]==q) ch[p][x]=nq,p=fa[p];
    28             }
    29         }
    30     }
    31     inline void Update(int x,int y){
    32         for(;x&&vis[x]!=y&&vis[x]!=-1;x=fa[x]){
    33             if(vis[x]!=0) vis[x]=-1;
    34             else vis[x]=y;
    35         }
    36     }
    37     inline void Work(){
    38         tot=0;
    39         for(int i=1;i<=n;++i)
    40             for(int j=1,x=1;j<=len[i];++j)
    41                 Update(x=ch[x][s[++tot]],i); 
    42         for(int i=1;i<=cnt;++i)
    43             if(vis[i]!=-1){
    44                 int x=vis[i];
    45                 ans[x]+=l[i]-l[fa[i]];
    46             }
    47         for(int i=1;i<=n;++i)
    48             printf("%d
    ",ans[i]);
    49     } 
    50 }SAM; 
    51 
    52 int main(){
    53     cin>>n;getchar();
    54     for(int i=1;i<=n;++i){
    55         char ch;
    56         SAM.lst=1;
    57         while((ch=getchar())!='
    '&&ch!=EOF){
    58             ch-='a';
    59             ++len[i];s[++tot]=ch;
    60             SAM.Extend(ch);
    61         } 
    62     }
    63     SAM.Work();
    64     return 0;
    65 }
  • 相关阅读:
    《iOS-LLVM框架》
    《尚硅谷大数据之韩顺平Scala》
    《高性能Java-缓存、序列化、String》
    《高性能Java-集合》
    《尚硅谷大数据课程Spark+Spark高级(内存解析+性能调优)》
    《Spatial Transformer Networks》
    《Relational inductive biases, deep learning, and graph networks》
    《[论文笔记]Relational inductive biases, deep learning, and graph network》
    SSD:TensorFlow中的单次多重检测器
    YOLO: 3 步实时目标检测安装运行教程 [你看那条狗,好像一条狗!]
  • 原文地址:https://www.cnblogs.com/LI-dox/p/11235574.html
Copyright © 2011-2022 走看看