• 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 }
  • 相关阅读:
    自动化测试全聚合
    选择排序(JAVA实现)
    插入排序(JAVA实现)
    冒泡排序(JAVA实现)
    快速排序(java实现)
    Python+页面元素高亮源码实例
    (原创)Python 自动化测试框架详解
    Python+requests库 POST接口图片上传
    基于Python + requests 的web接口自动化测试框架
    python 创建mysql数据库
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10083930.html
Copyright © 2020-2023  润新知