1. 程式人生 > >Crazy Search 雜湊

Crazy Search 雜湊

給定一個字串,其中含有不同的字母數量為m,現在求這個字串中有多少個長度為n且長的互不相同的字元子串

舉個例子, n=3, m=4 ,字串 "daababac". 長度為3的不同的子串分別是: "daa"; "aab"; "aba"; "bab"; "bac". 因此, 答案是5.

Input

第一行是兩個整數n,m,,一個空格隔開。 接下來一行是我們要解決的字串.( 你可以認為字串的長度不會超過一千六百萬。)Orz我讀錯題了,並不是字串長度不超過1600萬,是合理hash之後的hash的值不超過1600萬。Orz原諒我

Output

程式應該輸出一個整數,對應於給定文字中所找到的大小為n的不同子字串的數量。

輸入資料

3 4
daababac

輸出資料

5

Hint

輸入資料量龐大,推薦使用scanf

雜湊其實就是將字串變為數字儲存起來,不能用map標記,map有logn的複雜度

#include <stdio.h>
#include<algorithm>
#include<string.h>
#include<map>
using namespace std;
#define ULL unsigned long long
char a[1000000];
ULL p=223;
ULL c[1000000],b[1000000];
ULL d[1000000];
int main()
{
    int n,m;

    scanf("%d %d",&n,&m);
    a[0]=1;
    scanf("%s",a+1);
    int len=strlen(a);

    b[0]=1;
    for(int i=1;i<len;i++)
    {
        b[i]=b[i-1]*p;
    }
    c[0]=1;
    for(int i=1;i<len;i++)
    {
        c[i]=c[i-1]*p+a[i];
    }
    int ans=0;
    map<ULL,int> p;
    ULL w;int e=0;
    for(int i=n;i<len;i++)
    {

        d[e++]=c[i]-c[i-n]*b[i-(i-n)];
        
    }
    sort(d,d+e);
    e=unique(d,d+e)-d;
    printf("%d\n",e);
    return 0;
}