(线段树+kmp) 1828
来源:互联网 发布:ida pro linux 破解版 编辑:程序博客网 时间:2024/05/19 14:39
题意:给出一个字符串,有一些字母是喜欢的,有些不喜欢。
求出这个串的连续子串中不喜欢的长度不超过K的数目,其中重复的子串只算一个
思路:先是用线段树来记录每段字符串中不喜欢字母的个数。
用KMP的前一部分来处理子串的的每一段,,找到前面已经有该子串的
注意:要把判断子串的if放在find()外面,这样就减少了很多不必要的fin(),,这才在时间上才够。。
#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<set>using namespace std;#define N 1555#define H 100007bool map[N][N];int n;string s;string b;set<string> go;struct my{int left,right;int value;int mid;}t[4*N];int next[N];void build(int cur,int l,int r){//cout<<cur<<" "<<l<<' '<<r<<endl;t[cur].left=l;t[cur].right=r;t[cur].mid=(l+r)>>1;if (l!=r){build(cur<<1,l,t[cur].mid);build(cur<<1|1,t[cur].mid+1,r);t[cur].value=t[cur<<1].value+t[cur<<1|1].value;}else{if (b[s[l-1]-'a']=='1')t[cur].value=0;elset[cur].value=1;//cout<<l<<' '<<cur<<' '<<b[s[l-1]-'a']<<' '<<t[cur].value<<endl;}}int find(int cur,int l,int r){//cout<<cur<<' '<<l<<' '<<r<<' '<<t[cur].value<<endl;if (l==t[cur].left && r==t[cur].right){return t[cur].value;}int m=t[cur].mid;int L=cur<<1,R=cur<<1|1;if (r<=m)return find(L,l,r);else if (l>m)return find(R,l,r);else{return find(L,l,m)+find(R,m+1,r);}}void get_next(int i){int j=i-1;next[i]=j;int k=j;while (i<n){if (j==k || s[i]==s[j]){i++;j++;next[i]=j;}elsej=next[j];}}int main(){freopen("in.txt","r",stdin);int i,j,k;int ncases;cin>>ncases;string cur;while (ncases--){cin>>s;cin>>b;scanf("%d",&k);n=s.size();build(1,1,n);int ans=0;go.clear();for (i=1;i<=n;i++)for (j=i;j<=n;j++)map[i][j]=false;for (i=1;i<=n;i++){get_next(i-1);for (j=i;j<=n;j++) if (next[j]>=i){map[j-(next[j]-i)][j]=true;}}for (i=1;i<=n;i++){for (j=i;j<=n;j++) if (!map[i][j]) if (find(1,i,j)<=k){//if (!map[i][j]){//cout<<i<<' '<<j<<endl;ans++;} }elsebreak;}cout<<ans<<endl;}return 0;}
Description
Minakami Yuki 很喜欢字符串,作为一个犯中二病的熊孩子,她只喜欢某些特定的小写字母,如果一个字符串包含了多于K个她不喜欢的字母,她就认为这是一个“坏串”。有一天她看到了一个只由小写字母组成的字符串,她想知道这个字符串的哪些子串不是“坏串”。因为她还要努力研究奇怪的哲学知识,这个问题就由你来计算了。
注意注意如果一个相同的子串出现在了原串的多个位置,只能算作一次喵~
Input
本题有多组测试数据,Input的第一行是一个整数T(T<=100),是测试数据的组数。
接下来T组数据,每组由三行构成。
第一行是一个字符串S,长度不超过1500,是Yuki看到的字符串。
第一行是一个长度为26的01串,代表Yuki喜不喜欢每个字母,从'a'到'z'。'0'代表不喜欢,'1'代表喜欢。
第三行是一个整数K,0<=K<=(S的长度),表示子串中最多所能包含的不喜欢的字母个数
Output
输出T行,每行一个整数,即满足条件子串的个数
Sample Input
2
ababab
01000000000000000000000000
1
acbacbacaa
00000000000000000000000000
2
Sample Output
5
8
Hint
子串是字符串中连续的一段,也可以包含原串本身。
- (线段树+kmp) 1828
- hdu Moles(线段树&KMP)
- 【Hash\KMP\线段树】文明的复兴
- 线段树+KMP-hdu-4125-Moles
- HDU 4125 Moles 线段树+KMP
- hdu 4763 Theme Section(扩展kmp+线段树)
- poj 3167 Cow Patterns (kmp + 线段树/树状数组)
- 51nod 1600 Simple KMP 后缀自动机+树链剖分+线段树
- 2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛(G. Query on a string)kmp+线段树
- ACdream 1116 扩展KMP 线段树区间累加 Fib数列的矩阵加速
- 17年ICPC新疆网络赛G Query on a string(线段树 KMP)
- BZOJ 3942 浅谈线段树维护哈希值+KMP优化暴力匹配
- 初识线段树(线段树总结)
- codevs1080线段树练习(线段树)
- poj2777-线段树应用(线段覆盖)
- 线段树(poj2528)
- 线段树(1)
- poj2823(线段树)
- 安装windows 服务出错
- 是否出现2个事件记录,补偿
- 数据库导入错误提示:#1065 – Query was empty的处理方法
- 树套树练手题
- Check Box 的使用
- (线段树+kmp) 1828
- BlueTooth知识ABC
- 利用Java进行MySql数据库的导入和导出
- Improve the Recipe App With a Better Detail View Controller
- 可识别动物 宝马第三代夜视系统升级
- ext限制输入长度
- LNMP架设 (备忘录)
- MySQL 主主同步配置
- 修改resx文件解决“System.StackOverflowException”类型的异常