http://codeforces.com/problemset/problem/271/D
https://codeforces.com/blog/entry/6668
X. Suffix Trie
http://www.voidcn.com/article/p-bbqykeub-bph.html
X. Suffix Array
https://www.itbox.info/p/1506597/codeforces-good-substrings
You've got string s, consisting of small English letters. Some of the English letters are good, the rest are bad.
A substring s[l...r] (1 ≤ l ≤ r ≤ |s|) of string s = s1s2...s|s| (where |s| is the length of string s) is string slsl + 1...sr.
The substring s[l...r] is good, if among the letters sl, sl + 1, ..., sr there are at most k bad ones (look at the sample's explanation to understand it more clear).
Your task is to find the number of distinct good substrings of the given string s. Two substrings s[x...y] and s[p...q] are considered distinct if their content is different, i.e. s[x...y] ≠ s[p...q].
Input
The first line of the input is the non-empty string s, consisting of small English letters, the string's length is at most 1500 characters.
The second line of the input is the string of characters "0" and "1", the length is exactly 26 characters. If the i-th character of this string equals "1", then the i-th English letter is good, otherwise it's bad. That is, the first character of this string corresponds to letter "a", the second one corresponds to letter "b" and so on.
The third line of the input consists a single integer k (0 ≤ k ≤ |s|) — the maximum acceptable number of bad characters in a good substring.
Output
Print a single integer — the number of distinct good substrings of string s.
Examples
input
Copy
ababab 01000000000000000000000000 1
output
Copy
5
input
Copy
acbacbacaa 00000000000000000000000000 2
output
Copy
8
Note
In the first example there are following good substrings: "a", "ab", "b", "ba", "bab".
In the second example there are following good substrings: "a", "aa", "ac", "b", "ba", "c", "ca", "cb"
给定一个字母串s,给定每个字母是good/bad字母;
一个子串如果包含的bad字母数<=k,则为一个good串;
求有多少个good串。
https://codeforces.com/blog/entry/6662一个子串如果包含的bad字母数<=k,则为一个good串;
求有多少个good串。
At first, build a trie containing all suffixes of given string (this structure is also called explicit suffix tree). Let's iterate over all substrings in order of indexes' increasing, i. e. first [1...1], then [1...2], [1...3], ..., [1...n], [2...2], [2...3], ..., [2...n], ... Note, that moving from a substring to the next one is just adding a single character to the end. So we can easily maintain the number of bad characters, and also the "current" node in the trie. If the number of bad characters doesn't exceed k, then the substring is good. And we need to mark the corresponding node of trie, if we never did this before. The answer will be the number of marked nodes in the trie.
There is also an easier solution, where instead of trie we use Rabin-Karp rolling hash to count substrings that differ by content. Just sort the hashes of all good substrings and find the number of unique hashes (equal hashes will be on adjacent positions after sort). But these hashes are unreliable in general, so it's always better to use precise algorithm.
Using
Trie
to solve this problem is quite comfortable.- Create a
root
node. - Enumerate the start point of the substring in the string. Then enumerate the end of the substring. And at the same time, travel the
Trie
. If current node is valid and not marked inTrie
, ++ans!
Quite easy to code (also 32 lines), and the memory cost is quite low, runs fast, too: 3098298 3105955 I've read the official tutorial & many other people's submissions. I found this problem could be solve by
Suffix Array
, RK Hash
, ... I learnt a lot from all you guys, especially Robert's RK hash: 3106330X. Suffix Trie
http://www.voidcn.com/article/p-bbqykeub-bph.html
int b[N],k;
int ch[N*N][30],val[N*N];//trie
int root,num;
void insert(int l,int r)
{
int u=0;
for(int i=l;i<r;i++)
{
int id=s[i]-'a';
if(!ch[u][id])
ch[u][id]=++num;
u=ch[u][id];
val[u]=1;
}
val[u]=1;//
}
int query(int l,int r)
{
int res=0,cnt=0;
int u=0;
for(int i=l;i<r;i++)
{
int id=s[i]-'a';
u=ch[u][id];
if(a[id]=='0')
cnt++;
if(cnt<=k)
res+=val[u],val[u]=0;//val[u]清零
else
return res;
}
return res;
}
int main()
{
while(cin>>s>>a>>k)
{
int ans=0;
memset(ch,0,sizeof(ch));
num=0;
int len=s.length();
for(int i=0;s[i];i++)//把所有的substring插入到Trie
insert(i,len);
for(int i=0;s[i];i++)//O(n^2)
ans+=query(i,len);
cout<<ans<<endl;
}
return 0;
}
X. Suffix Array
https://www.itbox.info/p/1506597/codeforces-good-substrings