计蒜客 阿里天池的新任务 简单 KMP轻松水

阿里“天池”竞赛平台近日推出了一个新的挑战任务:对于给定的一串 DNA 碱基序列 tt,判断它在另一个根据规则生成的 DNA 碱基序列 ss中出现了多少次。

首先,定义一个序列 ww

\displaystyle w_{i} =

{b,(wi1+a)modn,i=0i>0{b,i=0(wi−1+a)modn,i>0
wi={b,(wi1+a)modn,i=0i>0

接下来,定义长度为 nn 的 DNA 碱基序列 ss(下标从 00 开始):

\displaystyle s_{i} =

A,T,G,C,(LwiR)(wi mod 2=0)(LwiR)(wi mod 2=1)((wi<L)(wi>R))(wi mod 2=0)((wi<L)(wi>R))(wi mod 2=1){A,(L≤wi≤R)∧(wi mod 2=0)T,(L≤wi≤R)∧(wi mod 2=1)G,((wiR))∧(wi mod 2=0)C,((wiR))∧(wi mod 2=1)
si=A,T,G,C,(LwiR)(wi mod 2=0)(LwiR)(wi mod 2=1)((wi<L)(wi>R))(wi mod 2=0)((wi<L)(wi>R))(wi mod 2=1)

其中 \land 表示“且”关系,\lor 表示“或”关系,a\ \mathrm{mod}\ ba mod b 表示 aa 除以 bb 的余数。

现给定另一个 DNA 碱基序列 tt,以及生成 ss 的参数 n , a , b , L , Rn,a,b,L,R,求 tt 在 ss 中出现了多少次。

输入格式

数据第一行为 55 个整数,分别代表 n , a , b , L , Rn,a,b,L,R。第二行为一个仅包含ATGC的一个序列 tt

数据保证 0 < a < n,0<a<n, 0 \le b < n,0b<n, 0 \le L \le R < n,0LR<n, |t| \le 10^{6}t106a,na,n 互质。

对于简单版本,1 \leq n \leq 10^{6}1n106

对于中等版本,1 \leq n \leq 10^{9}, a = 11n109,a=1

对于困难版本,1 \leq n \leq 10^{9}1n109

输出格式

输出一个整数,为 tt 在 ss 中出现的次数。

样例说明

对于第一组样例,生成的 ss 为TTTCGGAAAGGCC

样例输入1

13 2 5 4 9
AGG

样例输出1

1

样例输入2

103 51 0 40 60
ACTG

样例输出2

5

模拟一遍题意 进行kmp算法 统计个数即可

#include 
#include 
#include 
#include 
#include 
using namespace std;
const int MAX_N = 1e6+5;
int Next[MAX_N];
char mo[MAX_N];
char str[MAX_N];
int w[MAX_N];
int n2,n1;
void getnext(){
    int i = 0,j = -1;
    while(i=L){
            if(w[i]%2==1) {
                    str[i] = 'T';
                    continue;
            }
            else if(w[i]%2==0){
                 str[i]= 'A';
                continue;
            }
        }
        else if(w[i]R){
            if(w[i]%2==0){
                str[i] = 'G';
                continue;
            }
            else if(w[i]%2==1){
                str[i] = 'C';
                continue;
            }
        }
    }
    Next[0]=-1;
    getnext();
   printf("%d\n",kmp());
    return 0;
}


你可能感兴趣的:(ACM,KMP)