【题解】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);
}
posted @ 2020-10-07 16:53  破壁人五号  阅读(126)  评论(0编辑  收藏  举报