Codechef2015 May - Chef and Strings (后缀自动机)

用后缀自动机统计出出现1~n次的串的数量f[i]

对于ans[k]=sigma(f[i]*C(i,k)) i>=k

  1 const maxn=10008;
  2       mo=1000000007;
  3 var    a,f,rig:array[0..maxn] of dword;
  4     nt:array[0..maxn,‘a‘..‘z‘] of longint;
  5     last,sum,i:dword;
  6     s:ansistring;
  7     eg:array[0..maxn*2] of record nt,v:dword; end;
  8     lt:array[0..maxn] of dword;
  9     el:dword;
 10
 11     time:array[0..maxn] of qword;
 12     T,j,TT:dword;
 13     ans:array[0..maxn] of qword;
 14     C:array[-1..5000,-1..5000] of qword;
 15     du,g:array[0..maxn] of longint;
 16     b:array[0..1000000] of longint;
 17 procedure SAM_init; inline;
 18 begin
 19     fillchar(f,sizeof(f),255);
 20     fillchar(nt,sizeof(nt),255);
 21     fillchar(a,sizeof(a),0);
 22     fillchar(rig,sizeof(rig),0);
 23     el:=0;
 24     fillchar(lt,sizeof(lt),0);
 25     fillchar(ans,sizeof(ans),0);
 26     fillchar(du,sizeof(du),0);
 27     fillchar(g,sizeof(g),0);
 28     last:=0; sum:=0;
 29 end;
 30
 31 procedure SAM_ins(ch:char); inline;
 32 var next,p,np,q,nq:longint;
 33 begin
 34     inc(sum); p:=last; np:=sum; a[np]:=a[p]+1; last:=np;  rig[np]:=1;
 35     while (p<>-1) and (nt[p][ch]=-1) do begin nt[p][ch]:=np; p:=f[p]; end;
 36     if p=-1 then f[np]:=0 else
 37     begin
 38         q:=nt[p][ch];
 39         if a[p]+1=a[q] then f[np]:=q else
 40         begin
 41             inc(sum); nq:=sum; a[nq]:=a[p]+1;
 42             nt[nq]:=nt[q];
 43             f[nq]:=f[q]; f[q]:=nq; f[np]:=nq;
 44             while (p<>-1) and (nt[p][ch]=q) do begin nt[p][ch]:=nq; p:=f[p]; end;
 45         end;
 46     end;
 47 end;
 48
 49 procedure SAM_visit1; inline;
 50 var i,l,r:longint;
 51     c:char;
 52 begin
 53     for i:=0 to sum do
 54         for c:=‘a‘ to ‘z‘ do
 55             if nt[i][c]<>-1 then inc(du[nt[i][c]]);
 56
 57
 58     l:=1; r:=1; b[1]:=0; g[0]:=1;
 59     while l<=r do
 60     begin
 61         for c:=‘a‘ to ‘z‘ do
 62             if nt[b[l]][c]<>-1 then
 63             begin
 64                 dec(du[nt[b[l]][c]]);
 65                 inc(g[nt[b[l]][c]],g[b[l]]);
 66                 if du[nt[b[l]][c]]=0 then
 67                 begin
 68                     inc(r);
 69                     b[r]:=nt[b[l]][c];
 70                 end;
 71             end;
 72         inc(l);
 73     end;
 74     for i:=1 to sum do inc(time[rig[i]],g[i]);
 75 end;
 76 procedure dfs(u:dword);
 77 var i:dword;
 78 begin
 79     i:=lt[u];
 80     while i<>0 do
 81     begin
 82         dfs(eg[i].v);
 83         rig[u]:=rig[u]+rig[eg[i].v];
 84         i:=eg[i].nt;
 85     end;
 86 end;
 87 procedure add(u,v:dword); inline;
 88 begin
 89     inc(el);
 90     eg[el].v:=v;
 91     eg[el].nt:=lt[u];
 92     lt[u]:=el;
 93 end;
 94 procedure SAM_rig; inline;
 95 begin
 96     el:=0;
 97     fillchar(lt,sizeof(lt),0);
 98     for i:=1 to sum do add(f[i],i);
 99     dfs(0);
100 end;
101 procedure main; inline;
102 var n,q,i,j:dword;
103     cnt:qword;
104 begin
105     if T<>1 then
106     begin
107         fillchar(time,sizeof(time),0);
108         SAM_init;
109     end;
110     readln(n,q);
111     readln(s);
112     SAM_init;
113     for i:=1 to n do SAM_ins(s[i]);
114     SAM_rig;
115     SAM_visit1;
116     for i:=1 to n do
117         for j:=i to n do ans[i]:=(ans[i]+C[j,i]*time[j]) mod mo;
118     for i:=1 to q do
119     begin
120         readln(j);
121         if j>n then writeln(0) else
122         writeln(ans[j]);
123     end;
124 end;
125 begin
126     C[0,0]:=1;
127     for i:=1 to 5000 do
128         for j:=0 to i do
129         begin
130             C[i,j]:=(c[i-1,j-1]+c[i-1,j]);
131             if C[i,j]>=mo then C[i,j]:=C[i,j]-mo;
132         end;
133     readln(T);
134     for TT:=1 to T do main;
135 end.
时间: 2024-10-13 23:49:18

Codechef2015 May - Chef and Strings (后缀自动机)的相关文章

CodeForces-204E:Little Elephant and Strings (后缀自动机)

The Little Elephant loves strings very much. He has an array a from n strings, consisting of lowercase English letters. Let's number the elements of the array from 1 to n, then let's denote the element number i as ai. For each string ai (1 ≤ i ≤ n) t

E. Three strings 广义后缀自动机

http://codeforces.com/problemset/problem/452/E 多个主串的模型. 建立一个广义后缀自动机,可以dp出每个状态的endpos集合大小.同时也维护一个R[]表示那个串出现过. 所以可以算出每个状态的dp[i][k]表示第k个串在第i个状态中出现的次数. 可以知道sigma dp[i][0...k]是等于  endpos集合的大小. 然后把这个贡献加到min(i)....max(i)中去就可以了 差分一下. #include <bits/stdc++.h>

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

传送门在这里. 大意: 给一堆字符串,询问每个字符串有多少子串在所有字符串中出现K次以上. 解题思路: 这种子串问题一定要见后缀自动机Parent树Dfs序统计出现次数都是套路了吧. 这道题统计子串个数,那么可以发现,若一个节点所对应的子串出现了K次,那么其贡献就是len,不需要考虑重复. 因为即使出现重复也是在两个位置. 那么只需统计以每个点结束的子串就好了. 之前的Dfs序就很套路了. 只需再跑一遍字符串,更新答案就好了. 代码: 1 #include<cstdio> 2 #include

poj2774 Long Long Message(后缀数组or后缀自动机)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Case Time Limit: 1000MS Description The little cat is majoring in physics in the capital of Byterland. A piece of sad news comes t

Codeforces 235C Cyclical Quest - 后缀自动机

Some days ago, WJMZBMR learned how to answer the query "how many times does a string x occur in a string s" quickly by preprocessing the string s. But now he wants to make it harder. So he wants to ask "how many consecutive substrings of s

HDOJ 5343 MZL&#39;s Circle Zhou 后缀自动机

对第二个串建SAM求出第二个串的以每个字符开头的不同子串的数目.. 再对第一个串建SAM,遍历自动机如果某个节点后面没有某个字符则答案加上这个节点的出现次数乘上以这个字符为开头的在第二个串中的不同子串的数目.. MZL's Circle Zhou Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 244    Accepted Sub

BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster [广义后缀自动机]

JZPGYZ - Sevenk Love Oimaster     Oimaster and sevenk love each other.       But recently,sevenk heard that a girl named ChuYuXun was dating with oimaster. As a woman's nature, sevenk felt angry and began to check oimaster's online talk with ChuYuXun

字符串(多串后缀自动机):HDU 4436 str2int

str2int Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 2082    Accepted Submission(s): 744 Problem Description In this problem, you are given several strings that contain only digits from '0'

字符串后缀自动机:Directed Acyclic Word Graph

trie -- suffix tree -- suffix automa 有这么一些应用场景: 即时响应用户输入的AJAX搜索框时, 显示候选列表. 搜索引擎的关键字个数统计. 后缀树(Suffix Tree): 从根到叶子表示一个后缀. 仅仅从这一个简单的描述,我们可以概念上解决下面的几个问题: P:查找字符串o是否在字符串S中 A:若o在S中,则o必然是S的某个后缀的前缀. 用S构造后缀树,按在trie中搜索字串的方法搜索o即可. P: 指定字符串T在字符串S中的重复次数. A: 如果T在S