• codeforces 235C. Cyclical Quest(后缀自动机)


    传送门

    解题思路:

    既然是询问循环字符串出现次数,那么第一步当然是要倍长。

    注意这里的贡献最好在广义后缀自动机中跑一遍匹配。

    注意一定要一直控制其长度否则会出现前段失配现象导致算了不该算的。

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 typedef long long lnt;
      5 struct sant{
      6     int tranc[26];
      7     int len;
      8     int pre;
      9 }s[2000000];
     10 struct pnt{
     11     lnt wgt;
     12     int vis;
     13 }p[2000000];
     14 struct ent{
     15     int twd;
     16     int lst;
     17 }e[2000000];
     18 int cnt;
     19 int fin;
     20 int siz;
     21 int n,Q;
     22 int has[2000000];
     23 int topo[2000000];
     24 char tmp[2000000];
     25 void Insert(int c)
     26 {
     27     int nwp,nwq,lsp,lsq;
     28     nwp=++siz;
     29     s[nwp].len=s[fin].len+1;
     30     p[nwp].wgt=1;
     31     for(lsp=fin;lsp&&!s[lsp].tranc[c];lsp=s[lsp].pre)
     32         s[lsp].tranc[c]=nwp;
     33     if(!lsp)
     34         s[nwp].pre=1;
     35     else{
     36         lsq=s[lsp].tranc[c];
     37         if(s[lsq].len==s[lsp].len+1)
     38             s[nwp].pre=lsq;
     39         else{
     40             nwq=++siz;
     41             s[nwq]=s[lsq];
     42             s[nwq].len=s[lsp].len+1;
     43             s[lsq].pre=s[nwp].pre=nwq;
     44             while(s[lsp].tranc[c]==lsq)
     45             {
     46                 s[lsp].tranc[c]=nwq;
     47                 lsp=s[lsp].pre;
     48             }
     49         }
     50     }
     51     fin=nwp;
     52     return ;
     53 }
     54 int main()
     55 {
     56     fin=++siz;
     57     scanf("%s",tmp+1);
     58     int len=strlen(tmp+1);
     59     for(int i=1;i<=len;i++)
     60         Insert(tmp[i]-'a');
     61     for(int i=1;i<=siz;i++)
     62         has[s[i].len]++;
     63     for(int i=1;i<=len;i++)
     64         has[i]+=has[i-1];
     65     for(int i=1;i<=siz;i++)
     66         topo[has[s[i].len]--]=i;
     67     for(int i=siz;i;i--)
     68     {
     69         int x=topo[i];
     70         p[s[x].pre].wgt+=p[x].wgt;
     71     }
     72     scanf("%d",&Q);
     73     while(Q--)
     74     {
     75         scanf("%s",tmp);
     76         len=strlen(tmp);
     77         int ln=len<<1;
     78         lnt ans=0;
     79         int root=1,l=0;
     80         for(int j=0;j<ln;j++)
     81         {
     82             int i=j%len;
     83             int c=tmp[i]-'a';
     84             while(root&&!s[root].tranc[c])
     85                 root=s[root].pre,l=s[root].len;
     86             root=s[root].tranc[c];
     87             if(!root)
     88                 root=1,l=0;
     89             else{
     90                 l++;
     91                 while(s[s[root].pre].len>=len&&s[root].pre)
     92                     root=s[root].pre,l=s[root].len;
     93                 if(p[root].vis!=Q+1&&l>=len)
     94                 {
     95                     ans+=p[root].wgt;
     96                     p[root].vis=Q+1;
     97                 }
     98             }
     99         }
    100         printf("%I64d
    ",ans);
    101     }
    102     return 0;
    103 }
  • 相关阅读:
    Vmware安装Ubuntu ==> 连网成功
    在 ns3.25中添加 plc(电力线载波) 模块
    Ubuntu12.04下安ns3.29及Ubuntu换源方法
    微信支付小程序版
    微信小程序打开外部链接
    linux下安装Mongodb
    延迟执行+异步 之代码分析1
    Vue入门
    实验一
    实验二
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10083930.html
Copyright © 2020-2023  润新知