【字符串hash】DNA
DNA
题目描述
小X身为奆老,兴趣爱好广泛,他还非常喜欢研究DNA序列……
小X进行了一项关于DNA序列研究,发现人某条染色体上的一段DNA序列中连续的k个碱基组成的碱基序列与做题的AC率有关!于是他想研究一下这种关系。
现在给出一段DNA序列,请帮他求出这段DNA序列中所有连续k个碱基形成的碱基序列中,出现最多的一种的出现次数。
小X进行了一项关于DNA序列研究,发现人某条染色体上的一段DNA序列中连续的k个碱基组成的碱基序列与做题的AC率有关!于是他想研究一下这种关系。
现在给出一段DNA序列,请帮他求出这段DNA序列中所有连续k个碱基形成的碱基序列中,出现最多的一种的出现次数。
输入
第一行为一段DNA序列,保证DNA序列合法,即只含有A,G,C,T四种碱基;
第二行为一个正整数k,意义与题目描述相同。
第二行为一个正整数k,意义与题目描述相同。
输出
一行,一个正整数,为题目描述中所求答案。
样例输入
AAAAA
1
样例输出
5
提示
对于这段DNA序列,连续的1个碱基组成的碱基序列只有A,共出现5次,所以答案为5。
记DNA序列长度为n。
下面给出每组数据的范围和满足性质情况:
【题解】
看清楚题意,是连续k个,然后可以重叠的,直接字符串Hash搞即可.
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N = 5e6+10; 4 typedef unsigned long long ull; 5 unordered_map < ull , int > Mp ; 6 unordered_map < ull , int > Cnt ; 7 8 ull h[N],p[N],base=131; 9 char str[N]; 10 ull get_hash( int L , int R){ 11 return h[R] - h[L-1] * p[ R - L + 1 ]; 12 } 13 14 ull t[N]; 15 int main() 16 { 17 int n,k; 18 scanf("%s%d",str+1,&k); 19 n = strlen(str+1); 20 p[0] = 1 ; 21 for( int i = 1 ; i <= n ; i++ ){ 22 h[i] = h[i-1] * base + str[i] - 'A' + 1 ; 23 p[i] = p[i-1] * base ; 24 if( i >= k ){ 25 ull tmp = get_hash( i-k+1 , i ) ; 26 Cnt[tmp] ++ ; 27 } 28 } 29 int ans = 0 ; 30 for( auto x : Cnt ){ 31 ans = max( ans , x.second ); 32 } 33 printf("%d\n",ans); 34 return 0 ; 35 } 36 /* 37 AAAAACCCCCGGGGGGGGTTTTTTTTTTTTTT 38 1 39 14 40 41 */