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. RTP 时间戳的处理

    RTP 时间戳的处理   在RTP传输音频数据时,一般选定逻辑时间戳速率与采样速率相同, 但是在传输视频数据时,必须使时间戳速率大于每帧的一个滴答(这样才能使图像回放更为平滑--<用TCP/IP ...

  2. java中==与equal()的区别

    ==和equal()都是用来判断两个变量是否相等的. (1)如果两个变量是基本类型变量,且都是数值型的(不一定数据类型相同),只要是值相同,将返回true; (2)如果两个变量是引用型变量,只有它们指 ...

  3. LeetCode-NQueensII

    经典的N皇后问题, 这里学到了一个非常牛的新方法(http://www.matrix67.com/blog/archives/266),用位运算来求解N皇后问题: 思路其实也很容易懂,一点都不复杂, ...

  4. list/tuple/dict/set

    一.list(列表) 内置类型,长度可变的有序集合,索引从0开始,索引为负数是标识从右开始取,最右边第一个是-1,以此类推.里面的元素可以是不同类型的. 1.定义:a = [] #空列表 2.获取长度 ...

  5. 关于JSP乱码问题

    关于jsp乱码问题的解决. 1 最基本的乱码问题. 这个乱码问题是最简单的乱码问题.一般新会出现.就是页面编码不一致导致的乱码. <%@ page language="java&quo ...

  6. jQuery中的append()和prepend(),after()和before()的差别

    jQuery中的append()和preappend(),after()和before()的差别 append()和prepend() 如果 <div class='a'> //<- ...

  7. Navicat Premium如何打开SQL文件.MDF和.LDF文件

    相信大家再装SQL Server时都会遇到一件很头疼的事情--装完SQL server之后发现没有启动程序.没有经验的会以为SQL SERVER安装失败了于是选择重装.可是呵呵,重装了4,5次还是一样 ...

  8. Oracle,用left join 替代 exists ,not exists,in , not in,提高效率

    Not IN问题 Exists,not Exists,in,not in 例如: FROM YSHB B WHERE YSHA.code=b.code ) 等同于 DELETE A FROM YSHA ...

  9. 创建了几个String对象?

    String str = "a"; 1个,在常量池中创建了一个字符串对象. String str = new String("a"); 2个,在常量池中创建了一 ...

  10. 在Docker中执行web应用

    启动一个简单的web 应用 使用社区提供的模板,启动一个简单的web应用,熟悉下各种Docker命令的使用: # docker run -d -P training/webapp python app ...