http://opentrains.snarknews.info/~ejudge/team.cgi?contest_id=001463

题目大意:
给出$n$个$x$,$m$个$y$,问有多少个hash函数 $y \equiv Ax + B (mod \ p)$, $p$是质数使得对$x$的集合加密后得到$y$的集合。

题解:

首先将所有$x$ mod $p$后去重。 剩下$n$个不同的$x$,$m$个不同的$y$。

ps: 以下公式均在mod p域下,因此省略mod p。

如果$A = 0$,那么只可能$m = 1$, $B = y_0$

如果$A \neq 0$,因为p是质数,所以$A * x_i  \neq A * x_j$.    那么必须$ n = m $

如果hash函数没有那个$B$,只有$y = Ax$怎么做呢?

考虑将每个数写成原根$g^i$的形式。

定义数组s, s[i] = 1 当且仅当 存在某个$x$,$x = g^i$.

定义数组t, t[i] = 1 当且仅当 存在某个$y$,$y = g^i$.

一个$A = g^k$合法当且仅当将s数组循环右移$k$位和t数组重合。

只要将t数组复制一遍做一次kmp就可以求出所有的$k$了。

再考虑如何把B给算进去.

假设$ y_i = A * x_i + B $. 两边对$i$求和。

记$sx = \sum\limits_{i=0}^{n - 1}x_i$,  $sy = \sum\limits_{i=0}^{n - 1}y_i$

那么有$sy = A * sx + n * B$,  $ B = \frac{sy - A * sx}{n}$ 是唯一的!

令$x_{i}^{'} = x_{i} - \frac{sx}{n}$  $y_{i}^{'} = y_{i} - \frac{sy}{n}$

问题就转化为$y_{i}^{'} = A * x_{i}^{'}$  这两个问题是完全等价的.

另外还有一些小细节:比如n = p的时候,分母n是没有逆元的,所以要特判断。

还有如果存在某个$x_{i}^{'} = 0$, 不存在某个$y_{i}^{'} = 0$ 或者反过来,都是无解的。(0不能表示为$g^i$, 所以也要特判)。

代码:

 #include <bits/stdc++.h>
using namespace std; #define MP make_pair
#define MAXN 1000010
int mod;
vector<int> xi, yi;
vector<pair<int, int> > ans; inline int add(int x, int y){return (x + y) % mod;}
inline int sub(int x, int y){return (x - y + mod) % mod;}
inline int mul(int x, int y){return 1ll * x * y % mod;} int power(int x, int p)
{
int res = ;
for (; p; p >>= )
{
if (p & ) res = mul(res, x);
x = mul(x, x);
}
return res;
} int inv(int x)
{
return power(x, mod - );
} int find_proot(int p)
{
static int pr[MAXN];
static int flag[MAXN];
for (int i = ; i < MAXN; ++i)
{
if (!flag[i]) pr[++pr[]] = i;
for (int j = ; j <= pr[] && i * pr[j] < MAXN; ++j)
{
flag[i * pr[j]] = ;
if (i % pr[j] == ) break;
}
} int g = ;
while (true)
{
int fl = , pp = p - ;
for (int i = ; i <= pr[] && pr[i] <= p; ++i)
{
if (pp % pr[i] == && power(g, pp / pr[i]) == )
{
fl = ;
break;
}
}
if (fl) return g; ++g;
}
return -;
} vector<int> calc_shift(int *s, int *t, int len)
{
static int nxt[MAXN];
nxt[] = nxt[] = ;
int j;
for (int i = ; i <= len; ++i)
{
j = nxt[i - ];
while (j && s[j] != s[i - ])
j = nxt[j];
nxt[i] = s[i - ] == s[j]? j + : ;
} for (int i = ; i < len; ++i)
t[len + i] = t[i]; j = ;
vector<int> res;
for (int i = ; i < * len - ; ++i)
{
while (j && t[i] != s[j])
j = nxt[j];
if (t[i] == s[j]) ++j;
if (j == len)
{
j = nxt[j];
res.push_back(i - len + );
}
}
return res;
} void solve(int n, int m, int p)
{
if (n < m) return;
if (m == ) ans.push_back(MP(, yi[]));
if (n != m) return;
if (n == p)
{
for (int a = ; a < p; ++a)
{
for (int b = ; b < p; ++b)
ans.push_back(MP(a, b));
}
return;
} int _n = inv(n);
int sx = , dx;
int sy = , dy; for (auto x: xi) sx = add(sx, x);
for (auto y: yi) sy = add(sy, y);
dx = mul(sx, _n);
dy = mul(sy, _n); int g = find_proot(p);
static int lg[MAXN];
memset(lg, -, sizeof(lg));
for (int i = ; i < p - ; ++i)
lg[power(g, i)] = i;
for (int i = ; i <= p - ; ++i)
assert(lg[i] != -); static int s[MAXN];
static int t[MAXN * ]; int x_zero = , y_zero = ;
for (auto x: xi)
{
if (x == dx) ++x_zero;
else s[lg[sub(x, dx)]] = ;
}
for (auto y: yi)
{
if (y == dy) ++y_zero;
else t[lg[sub(y, dy)]] = ;
}
if (x_zero != y_zero) return; vector<int> a_list = calc_shift(s, t, p - );
for (auto a: a_list)
{
a = power(g, a);
int b = mul(sub(sy, mul(a, sx)), _n);
ans.push_back(MP(a, b));
}
} int main()
{
//freopen("in.txt", "r", stdin);
int n, m, p, x, y;
scanf("%d %d %d", &n, &m, &p), mod = p;
for (int i = ; i < n; ++i)
{
scanf("%d", &x);
xi.push_back(x % p);
}
for (int i = ; i < m; ++i)
{
scanf("%d", &y);
yi.push_back(y);
}
sort(xi.begin(), xi.end());
xi.erase(unique(xi.begin(), xi.end()), xi.end()); sort(yi.begin(), yi.end());
yi.erase(unique(yi.begin(), yi.end()), yi.end()); n = xi.size();
m = yi.size(); solve(n, m, p); printf("%d\n", ans.size());
for (auto vv: ans) printf("%d %d\n", vv.first, vv.second); return ;
}

Petrozavodsk Summer-2015. Ivan Smirnov Contest 1 B Bloom的更多相关文章

  1. Root(hdu5777+扩展欧几里得+原根)2015 Multi-University Training Contest 7

    Root Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Su ...

  2. 2015 Multi-University Training Contest 6 solutions BY ZJU(部分解题报告)

    官方解题报告:http://bestcoder.hdu.edu.cn/blog/2015-multi-university-training-contest-6-solutions-by-zju/ 表 ...

  3. HDU 5360 Hiking(优先队列)2015 Multi-University Training Contest 6

    Hiking Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total S ...

  4. ACM-ICPC 2015 Shenyang Preliminary Contest B. Best Solver

    The so-called best problem solver can easily solve this problem, with his/her childhood sweetheart. ...

  5. hdu 5288 OO’s Sequence(2015 Multi-University Training Contest 1)

    OO's Sequence                                                          Time Limit: 4000/2000 MS (Jav ...

  6. HDU5294 Tricks Device(最大流+SPFA) 2015 Multi-University Training Contest 1

    Tricks Device Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) To ...

  7. hdu 5416 CRB and Tree(2015 Multi-University Training Contest 10)

    CRB and Tree                                                             Time Limit: 8000/4000 MS (J ...

  8. 2015多校联合训练赛 hdu 5308 I Wanna Become A 24-Point Master 2015 Multi-University Training Contest 2 构造题

    I Wanna Become A 24-Point Master Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 ...

  9. 2015 Multi-University Training Contest 10 hdu 5406 CRB and Apple

    CRB and Apple Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

随机推荐

  1. 防止继承和覆盖(PHP类)

    可能出现需求:我们不希望继承的类覆盖abstract类中的某个方法. 解决方案:我们可以在某个方法前面加上final关键词,可以防止继承的类覆盖它并实现继承类自己的版本. 继承类仍然可以访问和调用这些 ...

  2. Python的不同实现

    这里的实现指的是符合Python语言规范的Python解释程序以及标准库等.这些实现虽然实现的是同一种语言,但是彼此之间,特别是与CPython之间还是有些差别的. 下面分别列出几个主要的实现. 1. ...

  3. java中的Iterator接口

    Iterator接口 Iterator接口也是Java集合框架的成员,但它与Collection系列.Map系列的集合不一样:Collection系列集合.Map系列集合主要用于盛装其他对象,而Ite ...

  4. Python Hashtable的理解

           一个对象当其生命周期内的hash值不发生改变,而且可以跟其他对象进行比较时,这个对象就是Hashtable的.两者Hashtable的对象只有具有相同的hash值时才能判断为相同的对象. ...

  5. 算法笔记_167:算法提高 矩阵翻转(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 Ciel有一个N*N的矩阵,每个格子里都有一个整数. N是一个奇数,设X = (N+1)/2.Ciel每次都可以做这样的一次操作:他从矩阵 ...

  6. SpringBoot环境属性占位符解析和类型转换

    前提 前面写过一篇关于Environment属性加载的源码分析和扩展,里面提到属性的占位符解析和类型转换是相对复杂的,这篇文章就是要分析和解读这两个复杂的问题.关于这两个问题,选用一个比较复杂的参数处 ...

  7. python——修饰符

    修饰符基础--闭包 什么是闭包呢?标准的概念大家可以看wikipedia上的解释 举个例子: def do_add(base): def add(increase): return base + in ...

  8. 解决grep的结果无法显示文件名的问题

    有时候想在代码中执行某个关键词,会用下面的语句: find . -type f -name "*.java" | xargs grep -n "<keyword&g ...

  9. atitit.恒朋无纸化彩票系统数据接入通信协议

    atitit.恒朋无纸化彩票系统数据接入通信协议 深圳市恒朋科技开发有限公司 Shenzhen Helper Science & Technology Co., Ltd. 恒朋无纸化彩票系统数 ...

  10. JQuery.Page.js分页插件的使用

    1.简单直接贴代码 需要引用以下样式和脚本 <link href="~/Scripts/Page/pager.css" rel="stylesheet" ...