Crazy Search

链接:http://acm.hust.edu.cn/vjudge/problem/17714/origin

题目:Many people like to solve hard puzzles some of which may lead them to madness. One such puzzle could be finding a hidden prime number in a given text. Such number could be the number of different substrings of a given size that exist in the text. As you soon will discover, you really need the help of a computer and a good algorithm to solve such a puzzle.
Your task is to write a program that given the size, N, of the substring, the number of different characters that may occur in the text, NC, and the text itself, determines the number of different substrings of size N that appear in the text.

As an example, consider N=3, NC=4 and the text "daababac". The different substrings of size 3 that can be found in this text are: "daa"; "aab"; "aba"; "bab"; "bac". Therefore, the answer should be 5.

题意:有一个字符串,里面有nc种字符,问长度为n的连续字串共有多少种。

分析:字符串的数据结构除了kmp都是新学的,当时推荐用字符串哈希去做,现在想来气质这道题用字典树也是可以的,不过不知道会不会超时。。。在这道题里,把字符串变成nc进制的大数字,这样每个子串会有一个相应的值作为代号(预处理一个nc的n次幂,计算经常用到),不同字串的代号绝对不同。只要记录代号有几个就行了。我一开始用set记录的,结果超时了。。。。下次记得能用布尔数组标记就用bool来标记吧。。。

题解:
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define rt return
#define fr freopen("in.txt","r",stdin)
#define fw freopen("out.txt","w",stdout)
#define ll long long
#define ull unsigned long long
#define detie ios_base::sync_with_stdio(false);cin.tie(false);cout.tie(false)
#define pii pair
#define lowbit(x) x&(-x)
using namespace std;
#define maxi 0x3f3f3f3f
#define MAX 1000100

int c[150];
bool  v[16000010];
char s[MAX];
int quickpow(int x, int n)
{
	int ans = 1;
	while (n)
	{
		if (n & 1)ans *= x;
		n /= 2;
		x *= x;
	}
	rt ans;
}

int main()
{
	//fr;
	detie;
	int n, nc;
	scanf("%d %d", &n, &nc);
	scanf("%s", s);
	int len = strlen(s);
	for (int i = 0, j = 0; i < len&&j < nc; i++)
		if (!c[s[i]])c[s[i]] = j++;
	int num = 0;
	int t = quickpow(nc, n - 1);
	for (int i = 0; i < n; i++)
		num = num*nc + c[s[i]];
	v[num] = true;
	int ans = 1;
	for (int i = 0; i + n < len; i++)
	{
		num = (num - c[s[i]] * t)*nc + c[s[i + n]];
		if (!v[num]){
			v[num] = true;
			ans++;
		}
	}
	printf("%d\n", ans);
	rt 0;
}

你可能感兴趣的:(字符串哈希)