Codeforces963D. Frequency of String

Posted Blue233333

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces963D. Frequency of String相关的知识,希望对你有一定的参考价值。

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

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

互不相同的询问串,不同的长度会只有根号个。而每个长度的出现次数都是n级别的,因此总的出现次数是$n\sqrt{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\n",ans[i]);
135     return 0;
136 }
View Code

 

以上是关于Codeforces963D. Frequency of String的主要内容,如果未能解决你的问题,请参考以下文章

codeforces 963B Destruction of a Tree

Codeforces 963 A. Alternating Sum (逆元)

Codeforces 963 A. Alternating Sum (逆元)

CodeForces-1082E Increasing Frequency

CodeForces - 963B Destruction of a Tree (dfs+思维题)

Codeforces 963A Alternating Sum 数论+数学