P6871 [COCI2013-2014#6] HASH 题解
这明显就是一道较为基础的双向搜索问题。
首先,我们可以直接暴力搜索,时间复杂度为
但我们可以双向搜索,左边的初始值为 0,搜到一半,搞一个数组记录一下个数。时间复杂度
右边初始值为
重点在这个逆运算咋求。
首先,一个数
令原来的 Hash 值为
用
那么
注意到这里与的是
又因为
所以
将
参考代码
#include <bits/stdc++.h>
using namespace std;
int n, K, m, inv, cnt[1 << 25];
long long ans;
void dfs1(int dep, int v) {
if (!dep) {
++cnt[v];
return;
}
for (int i = 1; i <= 26; ++i)
dfs1(dep - 1, ((v * 33) ^ i) % m);
}
void dfs2(int dep, int v) {
if (!dep) {
ans += cnt[v];
return;
}
for (int i = 1; i <= 26; ++i)
dfs2(dep - 1, 1ll * (v ^ i) * inv % m);
}
int main() {
scanf("%d%d%d", &n, &K, &m);
m = 1 << m;
for (int i = 1; i < m; ++i)
if (i * 33 % m == 1) inv = i;
dfs1(n / 2, 0);
dfs2((n + 1) / 2, K);
printf("%lld", ans);
}