POJ1186 方程的解数
Posted xcysblog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ1186 方程的解数相关的知识,希望对你有一定的参考价值。
与其说这题是双向广搜板子不如说是哈希表板子...
就像邻接表一样,哈希表挂的链就是邻接表的边
把计数器记在边权上偷懒
一开始看错了条件。。。
记得先模再加mod再模,防止负数 GG
有一个显然的事情是,模数大了空间会大,
模数小了 find 时间长
代码:
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cctype> #include<cstdio> #include<cmath> using namespace std; const int MAXN = 10, mod = 333131; struct EDGE{ int nxt, to, val; EDGE(int NXT = 0, int TO = 0, int VAL = 0) {nxt = NXT; to = TO; val = VAL;} }edge[3375005]; int n, m, mid, ans, totedge; int k[MAXN], p[MAXN], x[MAXN]; int head[mod + 5]; inline int fastpow(int bot, int top) { register int ans = 1; while(top) { if(top & 1) ans *= bot; top >>= 1; bot *= bot; } return ans; } inline void add(int x, int y, int v) { edge[++totedge] = EDGE(head[x], y, v); head[x] = totedge; return; } inline void insrt(int res) { register int tmp = 0; tmp = (res % mod + mod) % mod; for(int i = head[tmp]; i; i = edge[i].nxt) if(edge[i].to == res) { ++edge[i].val; return; } add(tmp, res, 1); return; } void lfs(int pos, int sig) { if(pos > mid) { insrt(sig); return; } int tmp = 0; for(int i = 1; i <= m; ++i) { x[pos] = i; tmp = k[pos] * fastpow(i, p[pos]); lfs(pos + 1, sig + tmp); } return; } void rfs(int pos, int sig) { if(pos <= mid) { register int tmp = ((-sig) % mod + mod) % mod; for(int i = head[tmp]; i; i = edge[i].nxt) if(edge[i].to == -sig) { ans += edge[i].val; return; } return; } int tmp = 0; for(int i = 1; i <= m; ++i) { x[pos] = i; tmp = k[pos] * fastpow(i, p[pos]); rfs(pos - 1, sig + tmp); } return; } int main() { scanf("%d%d", &n, &m); mid = (n >> 1); for(int i = 1; i <= n; ++i) scanf("%d%d", &k[i], &p[i]); lfs(1, 0); rfs(n, 0); printf("%d ", ans); return 0; }
以上是关于POJ1186 方程的解数的主要内容,如果未能解决你的问题,请参考以下文章