您的位置:首页 > 编程语言 > Go语言

Codeforces 271D Good Substrings 暴力+Trie

2017-04-28 15:41 330 查看
点击打开链接

题意:string s长度<=1500,字母表a中1代表bad,问s中有多少个不同的substring(s[l]~s[r])满足bad字符不超过k个? 

枚举substring 开头 直到右端点R非法 map标记重复,O(n^2logn) TLE了

在标记重复上进行优化,用Trie保存所有的substring,枚举开头,遍历Trie,若该结点没访问过,标记后ans++即可 O(n^2)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e3+20;
string s,a;
int b
,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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: