string string string HDU
来源:互联网 发布:宝贝标题优化工具 编辑:程序博客网 时间:2024/05/16 10:25
Uncle Mao is a wonderful ACMER. One day he met an easy problem, but Uncle Mao was so lazy that he left the problem to you. I hope you can give him a solution.
Given a string s, we define a substring that happens exactlyk Input The first line contains an integer T (T≤100 ) implying the number of test cases.
For each test case, there are two lines:
the first line contains an integerk (k≥1 ) which is described above;
the second line contain a strings (length(s)≤105 ).
It's guaranteed that∑length(s)≤2∗106 . Output For each test case, print the number of the important substrings in a line.
Sample Input Sample Output
Given a string s, we define a substring that happens exactly
times as an important string, and you need to find out how many substrings which are important strings.
For each test case, there are two lines:
the first line contains an integer
the second line contain a string
It's guaranteed that
22abcabc3abcabcabcabc
69
题意:给你一个数字k,给你一个串,让你求出有多少子串是恰好出现k次的。
思路:后缀数组啊,按照sa【i】的顺序排列一下,然后框定一长度为k的区间,求height数组在这段区间的最小值,最小值一定是满足部分条件的,如果这个长度为k的区间上面的字符串或者下面的字符串有重复,那么需要减去他们之间的最大值。这就是一个区间的贡献。但是注意当k为1的时候单独讨论一下。
#include<iostream>#include<algorithm>#include<cstdlib>#include<cstdio>#include<cstring>#include<vector>#include<cmath>#include<complex>#include<queue>using namespace std;const int MAXN=1e5+10;char s[MAXN];int t1[MAXN],t2[MAXN],cc[MAXN],x[MAXN],sa[MAXN],Rank[MAXN],height[MAXN],Min[MAXN][50],kkk;int len;bool cmp(int *y,int a,int b,int k){ int a1=y[a]; int b1=y[b]; int a2=a+k>=len ? -1:y[a+k]; int b2=b+k>=len ? -1:y[b+k]; return a1==b1 && a2==b2;}int make_sa(){ int *x=t1,*y=t2; int m=26; for(int i=0; i<m; i++) cc[i]=0; for(int i=0; i<len; i++) ++cc[x[i]=s[i]-'a']; for(int i=1; i<m; i++) cc[i]+=cc[i-1]; for(int i=len-1; i>=0; i--) sa[--cc[x[i]]]=i; for(int k=1; k<=len; k<<=1) { int p=0; for(int i=len-k; i<len; i++) y[p++]=i; for(int i=0; i<len; i++) if( sa[i]>=k ) y[p++]=sa[i]-k; for(int i=0; i<m; i++) cc[i]=0; for(int i=0; i<len; i++) ++cc[x[y[i]]]; for(int i=1; i<m; i++) cc[i]+=cc[i-1]; for(int i=len-1; i>=0; i--) sa[--cc[x[y[i]]]]=y[i]; swap(x,y); m=1; x[sa[0]]=0; for(int i=1; i<len; i++) x[sa[i]]=cmp(y,sa[i],sa[i-1],k) ? m-1:m++; if( m>=len ) break; }}void make_height(){ for(int i=0; i<len; i++) Rank[sa[i]]=i; height[0]=0; int k=0; for(int i=0; i<len; i++) { if(!Rank[i]) continue; int j=sa[Rank[i]-1]; if(k) k--; while(s[i+k]==s[j+k]) k++; height[Rank[i]]=k; }}void RMQ(){ for(int i=0; i<len; i++) Min[i][0]=height[i]; for(int j=1; j<31; j++) for(int i=0; i<len; i++) { if(i+(1<<j)-1<len) { Min[i][j]=min(Min[i][j-1],Min[i+(1<<(j-1))][j-1]); } }}int query(int st,int en){ int kk=(int)((log(en-st+1))/log(2.0)); return min(Min[st][kk],Min[en-(1<<kk)+1][kk]);}int main(){ int t; scanf("%d",&t); while(t--) { scanf("%d %s",&kkk,s); len=strlen(s); make_sa(); make_height(); long long sum=0; RMQ(); height[len]=0; for(int i=kkk-1; i<len; i++) { int x=((i-kkk+2<=i)?query(i-kkk+2,i):(len-sa[i]))-max(height[i+1],height[i-kkk+1]); if(x>0) sum+=x; } printf("%lld\n",sum); }}
阅读全文
0 0
- string string string HDU
- HDU 6194 string string string
- HDU 6194 string string string
- HDU 6194 string string string
- HDU 6194 string string string
- HDU 6194string string string
- hdu 6194 string string string
- hdu 6194 string string string
- HDU 6194 string string string
- String HDU
- string
- String
- String
- string
- string
- String
- string
- String
- POJ-1321-棋盘问题(搜索)
- 1028. List Sorting (25)
- 详解JavaScript中this的指向
- 购物相关
- JQuery语法基础
- string string string HDU
- 9.14
- 解密MySQL备份恢复的4种方法
- [luogu-2877]noip2016-day2-T2 蚯蚓 题解
- 手动封装OKhttp
- Activity的最佳实践
- 十二、Git基础命令汇总
- codeforces839cjourney解题报告
- shutil