• Codeforces963D. Frequency of String


    $n leq 100000$的一文本串,给$m leq 100000$个询问,每次问一小串在文本串的哪一个最短的子串里出现指定次数。注意,询问串互不相同,且总长度$leq 100000$。

    比赛时不会分析复杂度QAQ没想到这么简单

    互不相同的询问串,不同的长度会只有根号个。而每个长度的出现次数都是n级别的,因此总的出现次数是$nsqrt{n}$,只要想出$O(串长+出现次数)$的匹配算法就行了。

    然后SA,SAM,AC,bitset挑个写就行了。写了AC。

      1 //#include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 //#include<time.h>
      5 //#include<complex>
      6 #include<set>
      7 //#include<queue>
      8 #include<algorithm>
      9 #include<stdlib.h>
     10 using namespace std;
     11 
     12 #define LL long long
     13 int qread()
     14 {
     15     char c; int s=0; while ((c=getchar())<'0' || c>'9');
     16     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s;
     17 }
     18 
     19 //Pay attention to '-' , LL and double of qread!!!!
     20 
     21 int n,lq;
     22 #define maxn 200011
     23 struct Edge{int to,next;}edge[maxn<<1]; int first[maxn],le=2;
     24 void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;}
     25 
     26 set<int> ss[maxn]; int ls=0,bel[maxn];
     27 struct AC
     28 {
     29     struct Node{int ch[26],fail;}a[maxn];
     30     int num[maxn],size;
     31     AC() {size=0; memset(a[0].ch,0,sizeof(a[0].ch));}
     32     int insert(char *s,int id)
     33     {
     34         int now=0,m=strlen(s);
     35         for (int i=0;i<m;i++)
     36         {
     37             int p=s[i]-'a';
     38             if (!a[now].ch[p])
     39             {
     40                 int x=++size;
     41                 a[now].ch[p]=x;
     42             }
     43             now=a[now].ch[p];
     44         }
     45         num[id]=now;
     46         return now;
     47     }
     48     
     49     int que[maxn],head,tail;
     50     void makefail()
     51     {
     52         head=tail=0;
     53         for (int i=0;i<26;i++)
     54         {
     55             int u=a[0].ch[i];
     56             if (u) que[tail++]=u,a[u].fail=0;
     57         }
     58         while (head!=tail)
     59         {
     60             int x=que[head++];
     61             for (int i=0;i<26;i++)
     62             {
     63                 int u=a[x].ch[i];
     64                 if (!u) {a[x].ch[i]=a[a[x].fail].ch[i]; continue;}
     65                 que[tail++]=u;
     66                 a[u].fail=a[a[x].fail].ch[i];
     67             }
     68         }
     69     }
     70     void buildtree() {for (int i=1;i<=size;i++) in(a[i].fail,i);}
     71     
     72     void pei(char *s)
     73     {
     74         int n=strlen(s),now=0;
     75         for (int i=0;i<n;i++)
     76         {
     77             now=a[now].ch[s[i]-'a'];
     78             if (!bel[now]) bel[now]=++ls;
     79             ss[bel[now]].insert(i);
     80         }
     81     }
     82 }ac;
     83 
     84 int ques[maxn],kk[maxn],ll[maxn],ans[maxn];
     85 
     86 void bing(int x)
     87 {
     88     int Max=x;
     89     for (int i=first[x];i;i=edge[i].next)
     90     {
     91         Edge &e=edge[i];
     92         bing(e.to);
     93         if (ss[bel[e.to]].size()>ss[bel[Max]].size()) Max=e.to;
     94     }
     95     
     96     for (int i=first[x];i;i=edge[i].next)
     97     {
     98         Edge &e=edge[i]; if (e.to==Max) continue;
     99         for (auto j=ss[bel[e.to]].begin();j!=ss[bel[e.to]].end();j++) ss[bel[Max]].insert(*j);
    100     }
    101     if (Max!=x)
    102     {
    103         for (auto j=ss[bel[x]].begin();j!=ss[bel[x]].end();j++) ss[bel[Max]].insert(*j);
    104         bel[x]=bel[Max];
    105     }
    106     
    107     if (ques[x])
    108     {
    109         vector<int> p;
    110         for (auto j=ss[bel[x]].begin();j!=ss[bel[x]].end();j++) p.push_back(*j);
    111         int Ans=0x3f3f3f3f;
    112         for (unsigned int k=kk[ques[x]],j=k-1;j<p.size();j++) Ans=min(Ans,p[j]-p[j-k+1]);
    113         if (Ans==0x3f3f3f3f) ans[ques[x]]=-1;
    114         else ans[ques[x]]=Ans+ll[ques[x]];
    115     }
    116 }
    117 
    118 char s[maxn],t[maxn];
    119 int main()
    120 {
    121     scanf("%s",s); n=strlen(s);
    122     lq=qread();
    123     for (int i=1;i<=lq;i++)
    124     {
    125         kk[i]=qread();
    126         scanf("%s",t); ll[i]=strlen(t);
    127         ques[ac.insert(t,i)]=i;
    128     }
    129     
    130     ac.makefail();
    131     ac.buildtree();
    132     ac.pei(s);
    133     bing(0);
    134     for (int i=1;i<=lq;i++) printf("%d
    ",ans[i]);
    135     return 0;
    136 }
    View Code
  • 相关阅读:
    使用Kuboard界面在k8s上部署SpringCloud项目
    改造项目使用的Dockerfile文件
    在Kuboard上安装 Ingress Controller
    解决nexus仓库只能拉取不能推送的问题
    Logstash:运用 memcache 过滤器进行大规模的数据丰富
    Docker Compose配置文件详解(V3)
    Dockerfile 和 docker-compose.yml的区别
    实战---在Portainer中编排docker-compose.yml文件
    ctk-获取MANIFEST.MF中的数据
    继承时的析构函数
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8881614.html
Copyright © 2020-2023  润新知