【题解】LOJ#537. 「LibreOJ NOIP Round #1」DNA 序列【哈希】
题意
求字符串 \(S\) 中出现次数最多的长为 \(k\) 的子串。\(\Sigma=\{\texttt{A,G,C,T}\}\),\(n\leq 5\times 10^6\),\(k\leq 10\)。
题解
\(|\Sigma|^k\leq 4^{10}\),所以直接哈希,开个桶记录每种哈希值出现多少次。复杂度 \(O(|S| + |\Sigma| ^ {k})\)。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=5e6+10;
char s[N];
int buk[1<<20];
inline int c2i(char x){
switch(x){
case 'A':return 0;
case 'T':return 1;
case 'C':return 2;
case 'G':return 3;
}
}
int main(){
int k;
scanf("%s",s);
scanf("%d",&k);
int n=strlen(s);
int h=0;
for(int i=0;i<n;i++){
h=((h<<2)|c2i(s[i]))&((1<<(k*2))-1);
if(i>=k-1)buk[h]++;
}
int ans=0;
for(int i=0;i<(1<<20);i++)ans=max(buk[i],ans);
printf("%d",ans);
}