• codeforces 204E. Little Elephant and Strings(广义后缀自动机,Parent树)


    传送门在这里。

    大意:

      给一堆字符串,询问每个字符串有多少子串在所有字符串中出现K次以上。

    解题思路:

      这种子串问题一定要见后缀自动机Parent树Dfs序统计出现次数都是套路了吧。

    这道题统计子串个数,那么可以发现,若一个节点所对应的子串出现了K次,那么其贡献就是len,不需要考虑重复。

    因为即使出现重复也是在两个位置。

    那么只需统计以每个点结束的子串就好了。

    之前的Dfs序就很套路了。

    只需再跑一遍字符串,更新答案就好了。

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 const int N=400000;
      5 struct sant{
      6     int tranc[26];
      7     int len;
      8     int pre;
      9 }s[N];
     10 struct pnt{
     11     int hd;
     12     int ind;
     13     int oud;
     14     int col;
     15     int ans;
     16 }p[N];
     17 struct ent{
     18     int twd;
     19     int lst;
     20 }e[N];
     21 struct int_2{
     22     int l;
     23     int r;
     24     int no;
     25 }d[N];
     26 int n,k;
     27 int siz;
     28 int dfn;
     29 int cnt;
     30 int fin;
     31 char tmp[N];
     32 int ll[N],rr[N];
     33 int col[N];
     34 int lst[N];
     35 int line[N];
     36 int str[N];
     37 int lowbit(int x)
     38 {
     39     return x&(-x);
     40 }
     41 void update(int pos,int x)
     42 {
     43     while(pos&&pos<=dfn)
     44     {
     45         line[pos]+=x;
     46         pos+=lowbit(pos);
     47     }
     48     return ;
     49 }
     50 int query(int pos)
     51 {
     52     int ans=0;
     53     while(pos)
     54     {
     55         ans+=line[pos];
     56         pos-=lowbit(pos);
     57     }
     58     return ans;
     59 }
     60 bool cmp(int_2 x,int_2 y)
     61 {
     62     return x.r<y.r;
     63 }
     64 void ade(int f,int t)
     65 {
     66     cnt++;
     67     e[cnt].twd=t;
     68     e[cnt].lst=p[f].hd;
     69     p[f].hd=cnt;
     70     return ;
     71 }
     72 void Insert(int c,int pl)
     73 {
     74     int nwp,nwq,lsp,lsq;
     75     nwp=++siz;
     76     s[nwp].len=s[fin].len+1;
     77     p[nwp].col=pl;
     78     for(lsp=fin;lsp&&!s[lsp].tranc[c];lsp=s[lsp].pre)
     79         s[lsp].tranc[c]=nwp;
     80     if(!lsp)
     81         s[nwp].pre=1;
     82     else{
     83         lsq=s[lsp].tranc[c];
     84         if(s[lsq].len==s[lsp].len+1)
     85             s[nwp].pre=lsq;
     86         else{
     87             nwq=++siz;
     88             s[nwq]=s[lsq];
     89             s[nwq].len=s[lsp].len+1;
     90             s[lsq].pre=s[nwp].pre=nwq;
     91             while(s[lsp].tranc[c]==lsq)
     92             {
     93                 s[lsp].tranc[c]=nwq;
     94                 lsp=s[lsp].pre;
     95             }
     96         }
     97     }
     98     fin=nwp;
     99 }
    100 void Dfs(int x)
    101 {
    102     p[x].ind=++dfn;
    103     col[dfn]=p[x].col;
    104     for(int i=p[x].hd;i;i=e[i].lst)
    105     {
    106         int to=e[i].twd;
    107         Dfs(to);
    108     }
    109     p[x].oud=++dfn;
    110     col[dfn]=p[x].col;
    111 }
    112 int main()
    113 {
    114     scanf("%d%d",&n,&k);
    115     if(k>n)
    116     {
    117         for(int i=1;i<=n;i++)
    118             printf("%d ",0);
    119         return 0;
    120     }
    121     fin=++siz;
    122     for(int i=1;i<=n;i++)
    123     {
    124         ll[i]=rr[i-1]+1;
    125         rr[i]=rr[i-1];
    126         fin=1;
    127         scanf("%s",tmp);
    128         int len=strlen(tmp);
    129         for(int j=0;j<len;j++)
    130             str[++rr[i]]=tmp[j]-'a';
    131         for(int j=ll[i];j<=rr[i];j++)
    132         {
    133             Insert(str[j],i);
    134         }
    135     }
    136 
    137     for(int i=2;i<=siz;i++)
    138         ade(s[i].pre,i);
    139     Dfs(1);    
    140     for(int i=1;i<=siz;i++)
    141         d[i]=(int_2){p[i].ind,p[i].oud,i};
    142     std::sort(d+1,d+siz+1,cmp);
    143     int r=1;
    144     for(int i=1;i<=siz;i++)
    145     {
    146         while(r<=d[i].r)
    147         {
    148             if(!col[r])
    149             {
    150                 r++;
    151                 continue;
    152             }
    153             if(lst[col[r]])
    154                 update(lst[col[r]],-1);
    155             update(r,1);
    156             lst[col[r]]=r;
    157             r++;
    158         }
    159         r--;
    160         p[d[i].no].ans=query(d[i].r)-query(d[i].l-1);
    161     }
    162     for(int i=1;i<=n;i++)
    163     {
    164         long long int ans=0;
    165         int root=1;
    166         for(int j=ll[i];j<=rr[i];j++)
    167         {
    168             root=s[root].tranc[str[j]];
    169             while(p[root].ans<k)
    170                 root=s[root].pre;
    171             ans+=(long long)s[root].len;
    172         }
    173         printf("%I64d ",ans);
    174     }
    175     puts("");
    176     return 0;
    177 }
  • 相关阅读:
    Python – GitHub CentOS
    Python – GitHub Ubuntu
    学习jQuery Treeview一天的感受
    让我郁闷了一个下午的list为null
    在徘徊中前进的一天
    都是被逼的,被逼的
    和技术无关,生活中的一点感受
    我又错了
    忽然的感受
    学习jQuery的一天
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10083876.html
Copyright © 2020-2023  润新知