您的位置:首页 > 其它

2017 计蒜之道 初赛 第一场 阿里天池的新任务(简单)(KMP)

2017-05-23 16:06 302 查看
题目:

 18.8%

 2000ms

 262144K

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

\displaystyle
w_{i} = \begin{cases}b, & i = 0\\(w_{i-1} + a) \mod n, & i > 0\end{cases}w​i​​={​b,​(w​i−1​​+a)modn,​​​i=0​i>0​​

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

\displaystyle
s_{i} = \begin{cases}A , & (L \le w_{i} \le R) \land (w_{i}\ \mathrm{mod}\ 2 = 0)\\T , & (L \le w_{i} \le R) \land (w_{i}\ \mathrm{mod}\ 2 = 1)\\G , & ((w_{i} < L) \lor (w_{i} > R)) \land (w_{i}\ \mathrm{mod}\ 2 = 0)\\C , & ((w_{i} < L) \lor (w_{i} > R)) \land
(w_{i}\ \mathrm{mod}\ 2 = 1)\end{cases}s​i​​=​⎩​⎪​⎪​⎪​⎨​⎪​⎪​⎪​⎧​​​A,​T,​G,​C,​​​(L≤w​i​​≤R)∧(w​i​​ mod 2=0)​(L≤w​i​​≤R)∧(w​i​​ mod 2=1)​((w​i​​<L)∨(w​i​​>R))∧(w​i​​ mod 2=0)​((w​i​​<L)∨(w​i​​>R))∧(w​i​​ 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。第二行为一个仅包含
A
T
G
C
的一个序列 tt。

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

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

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

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

输出格式

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

样例说明

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


样例输入1

13 2 5 4 9
AGG


样例输出1

1


样例输入2

103 51 0 40 60
ACTG


样例输出2

5


思路:

按照题意构造主串,然后剩下的是一个KMP板子。。。

我WA了将近20发。。换了无数种方法,想了无数种可能。。。

最后发现。。。。我的next数组开成char型了。。。


代码:

#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<iostream>
#include<stack>
#include<queue>
#include<vector>
#include<algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define mod 10000007
#define debug() puts("what the fuck!!!")
#define N (1000020)
#define ll long long
using namespace std;
char s
,t
;
ll nxt
;
ll n,a,b,L,R,len_s,len_t;
char get_s(ll i)
{
ll wi=(b+i*a)%n;
if(wi>=L&&wi<=R)
{
if(wi&1)
return 'T';
else
return 'A';
}
else
{
if(wi&1)
return 'C';
else
return 'G';
}
}
void getnext()
{
ll j=0,k=-1;
nxt[0]=-1;
while(j<len_t)
{
if(k==-1||t[j]==t[k])
nxt[++j]=++k;
else
k=nxt[k];
}
}
ll kmp_cnt()
{
ll ans=0;
ll i,j=0;
if(len_s==1&&len_t==1)
{
if(s[0]==t[0])
return 1;
else
return 0;
}
getnext();
for(ll i=0;i<len_s;i++)
{
while(j>0&&s[i]!=t[j])
j=nxt[j];
if(s[i]==t[j])
j++;
if(j==len_t)
{
ans++;
j=nxt[j];
}
}
return ans;
}
int main()
{
while(~scanf("%lld%lld%lld%lld%lld",&n,&a,&b,&L,&R))
{
scanf("%s",t);
len_t=strlen(t);
len_s=n;
for(ll i=0;i<n;i++)
s[i]=get_s(i);
printf("%lld\n",kmp_cnt());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: