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. UISegmentedControl 修改字体大小 和 颜色

    UISegmentedControl 修改字体大小 和 颜色 大小: UIFont *font = [UIFont boldSystemFontOfSize:14.0f]; NSDictionary ...

  2. ZK框架笔记5、事件

            事件是org.zkoss.zk.ui.event.Event类,它通知应用程序发生了什么事情.每一种类型的事件都由一个特定的类来表示.         要响应一个事件,应用程序必须为事 ...

  3. OpenERP|ODOO高德地图应用

    发布时间:2015-04-06 11:01:37来源:http://www.chinamaker.net 在openerp中的fleet模块,每一个车辆都有地图应用.默认采用的是谷歌地图,但是在应用得 ...

  4. 《The Story of My Life》Introductiom - The Life and Work of Helen Keller

    Helen Keller was born on June 27,1880, in Tuscumabia, Alabama, to Captain Arthur Henry Keller, a Con ...

  5. jQuery上传插件Uploadify使用介绍

    以图纸资料上传为例,介绍Uploadify插件的使用,插件下载地址   http://www.uploadify.com/download/ 上传页面: 选择文件增加未上传界面: 上传成功预览界面: ...

  6. 深入理解linux系统的目录结构

    对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于我们用好linux系统只管重要,下面 ...

  7. golang中使用mongodb

    mgo简介 mongodb官方没有关于go的mongodb的驱动,因此只能使用第三方驱动,mgo就是使用最多的一种. mgo(音mango)是MongoDB的Go语言驱动,它用基于Go语法的简单API ...

  8. android 关于setWidth()和setHeight()没反应的问题

      在android开发过程中,对于控件的高度,宽度,虽然在xml中用android:layout_height="match_parent"设置了 高度(match_parent ...

  9. win10 清理winsxs文件夹

    dism /online /cleanup-image /startcomponentcleanup /resetbase

  10. SignalR IOS Android

    http://www.dotblogs.com.tw/toysboy21/archive/2014/03/24/144505.aspx https://www.youtube.com/watch?v= ...