穿

时间限制: 1 Sec  内存限制: 128 MB

题目描述

乌龟得到了他的基因组,一个只包含“ATCG”四种字母的字符串。乌龟想起科学家说,基因组中很多片段都多次重复出现,而且这种重复是很有意义的,于是他想计算一下自己基因组里片段的重复情况。

给定一个基因组,其中一个长度为k的子串称为一个“k-片段”。乌龟希望你计算出基因组中不同的k-片段数量。例如,基因组“TACAC”的2-片段有“TA” ,“AC”,“CA”,“AC”,其中不同的片段数量有3个。
 

 

输入

三个整数n,k,R1,表示基因组的长度,片段的长度和数列生成的首项。基因组第i(1 in)个字符在Ri mod 4的值为0,1,2,3时分别为A, T,C,G

试题中使用的生成数列R定义如下:整数0≤R1<201701在输入中给出。对于i> 1,Ri =(Ri-1×6807 + 2831)mod 201701。
 

 

输出

一个整数,表示不同的k-片段的数量

 

样例输入

复制样例数据

20 2 37

样例输出

10

 

提示

数据规模 
30%的数据满足n≤10; 
100%的数据满足1≤n≤105,1≤k≤10

 

直接用c++中的string类,快速解决。。

/**/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue>

typedef long long LL;
using namespace std;

int n, k, r;
char s[] = "ATCG";
char str[100005];

int main()
{
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);

	scanf("%d %d %d", &n, &k, &r);
	if(k > n) {printf("0\n"); return 0;}
	str[1] = s[r % 4];
	for (int i = 2; i <= n; i++){
		str[i] = s[(r * 6807 % 201701 + 2831) % 201701 % 4];
		r = (r * 6807 % 201701 + 2831) % 201701;
	}
	string s1;
	map<string, int>mp;
	int ans = 0, cnt = 1;
	while(cnt <= k) s1 = str[cnt++] + s1;
	mp[s1] = 1, ans++;
	for (int i = k + 1; i <= n; i++){
		s1.pop_back();
		s1 = str[i] + s1;
		if(!mp[s1]) ans++, mp[s1] = 1;
	}
	printf("%d\n", ans);

	return 0;
}
/**/