#P4235. Hash?

    ID: 3147 远端评测题 1000~4500ms 188MiB 尝试: 0 已通过: 0 难度: 6 上传者: 标签>字符串哈希,HASH概率论,统计

Hash?

题目背景

zhoutb2333学习了哈希算法,他于是去统计给定一些字符串,其中有多少个本质不同的字符串。

但是zhoutb2333突发奇想,如果哈希采用的basebase每次随机,那么结果会变成什么样呢?

辣鸡出题人又出锅了!subtask3的数据有问题,现在统一将模数改为65537

题目来源:zhoutb2333

题目描述

他通过某种办法,获得了一个函数:int Rand(int x)int \ Rand(int \ x),它会等概率地返回一个[0,x)[0,x)中的整数。

他写下了这样的代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int x=10,maxn=35,maxlen=16010;
ll HASH[maxn];
const ll p=65537;
char str[maxlen];
ll Hash(){
    int base=Rand(x);
    ll ret=0;
    for(int i=1;str[i];i++)
        ret=(ret*base+str[i]-'a'+1)%p;
    return ret;
}
int main(){
    int ans=0,n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%s",str+1),HASH[i]=Hash();
    sort(HASH+1,HASH+n+1);
    HASH[0]=-1;
    for(int i=1;i<=n;i++)
        ans+=(HASH[i]!=HASH[i-1]);
    printf("%d\n",ans);
    return 0;
}

zhoutb2333想问你,给定一些字符串和参数xx,答案ansans的期望是多少呢?

65537=216+165537= 2^{16}+1是质数

参数xx在这个程序中是确定的1010,但是每次输入会给定。

输入格式

第一行三个整数x,Nx,N,表示basebase生成的参数和字符串的个数

接下来NN行每行一个字符串,字符串仅由小写字母组成。

输出格式

一行一个小数,表示答案ansans的期望,6553765537输出

即:如果你的答案为qp\frac{q}{p}gcd(p,q)=1gcd(p,q)=1),那么输出使得pxq (mod 65537px \equiv q \ (mod \ 65537的最小正整数xx。可以证明答案ansans一定为正有理数,并且这样的xx一定存在。

2 2
aa
aa
32770

3 6
i
dont
know
what
to
say
58261

提示

本题由33subtasksubtask组成,设MM为这NN个字符串中,每个字符串长度的最大值。

对于subtask 1subtask \ 11N8,M10,x41 \le N \le 8 , M \le 10,x \le 4,分值为2020,时间限制为1s1s

对于subtask 2subtask \ 21N30,M500,x5001 \le N \le 30 , M \le 500,x \le 500,分值为5050,时间限制为1s1s

对于subtask 3subtask \ 31N5,M16000,x160001 \le N \le 5 , M \le 16000,x \le 16000,分值为3030,时间限制为4.5s4.5s

样例#1解释:

参数x=2x=2,那么可能的哈希basebase0,10,1

如果哈希第一个aa采用的basebase和第二个aabasebase相同,那么答案为11

如果两个basebase不相同,那么答案为22

分析发现这两种情况发生的概率相同,都是12\frac{1}{2},那么答案ansans的期望为112+212=321 * \frac{1}{2} + 2 * \frac{1}{2}=\frac{3}{2}。使得2x3 (mod 65537)2x \equiv 3 \ (mod \ 65537)的最小正整数xx3277032770

样例#2解释:

求得答案为539\frac{53}{9}。使得9x53 (mod 65537)9x \equiv 53 \ (mod \ 65537)的最小正整数xx5826158261

注意:本题允许手动开O2O2优化以避免被卡常数,方法如下:

%:pragma GCC optimize(2)
/*程序*/