[BZOJ3129][SDOI2013]方程(扩展Lucas定理+容斥)
来源:互联网 发布:冰川网络的手游有哪些 编辑:程序博客网 时间:2024/06/07 07:16
先介绍:把
证明见http://blog.csdn.net/xyz32768/article/details/78502117([JSOI2011]分特产)中的相关部分。
首先可以发现,对于任意的
再考虑
对于组合数,可以用扩展Lucas定理求得。
扩展Lucas定理链接:http://blog.csdn.net/clove_unique/article/details/54571216
代码:
#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;inline int read() { int res = 0; bool bo = 0; char c; while (((c = getchar()) < '0' || c > '9') && c != '-'); if (c == '-') bo = 1; else res = c - 48; while ((c = getchar()) >= '0' && c <= '9') res = (res << 3) + (res << 1) + (c - 48); return bo ? ~res + 1 : res;}const int N = 2e5 + 5, R = 4005, E = 14;typedef long long ll;int cnt, n1, n2, A1[E];ll bas[R], num[R], ex[R], PYZ, F[N];void exgcd(ll a, ll b, ll &x, ll &y) { if (!b) return (void) (x = 1, y = 0); exgcd(b, a % b, y, x); y -= a / b * x;}ll inv(ll a, ll LPF) { ll x, y; exgcd(a, LPF, x, y); x = (x % LPF + LPF) % LPF; return x;}ll qpow(ll a, ll b, ll LPF) { ll res = 1; while (b) { if (b & 1) (res *= a) %= LPF; (a *= a) %= LPF; b >>= 1; } return res;}ll crt() { ll ans = 0; int i; for (i = 1; i <= cnt; i++) (ans += ex[i] * (PYZ / num[i]) * inv(PYZ / num[i], num[i])) %= PYZ; return ans;}ll fac(ll n, ll x, ll LPF) { if (n < x) return F[n]; ll ans = qpow(F[LPF - 1], n / LPF, LPF); (ans *= F[n % LPF]) %= LPF; (ans *= fac(n / x, x, LPF)) %= LPF; return ans;}ll comb(ll n, ll m, ll x, ll LPF) { if (m > n) return 0; ll i; F[0] = 1; ll x1 = 0, x2 = 0, x3 = 0; for (i = 1; i < LPF; i++) F[i] = i % x ? F[i - 1] * i % LPF : F[i - 1]; for (i = n; i;) x1 += (i /= x); for (i = m; i;) x2 += (i /= x); for (i = n - m; i;) x3 += (i /= x); x1 -= x2 + x3; ll tmp = qpow(x, x1, LPF); x1 = fac(n, x, LPF); x2 = fac(m, x, LPF); x3 = fac(n - m, x, LPF); return (tmp * x1 % LPF) * (inv(x2, LPF) * inv(x3, LPF) % LPF) % LPF;}void init() { int i, x = PYZ, S = sqrt(PYZ); cnt = 0; for (i = 2; i <= S; i++) if (x % i == 0) { bas[++cnt] = i; num[cnt] = 1; while (x % i == 0) num[cnt] *= i, x /= i; } if (x > 1) bas[++cnt] = num[cnt] = x;}ll C(ll n, ll m) { int i; for (i = 1; i <= cnt; i++) ex[i] = comb(n, m, bas[i], num[i]); return crt();}void work() { int i, j, n, m, x; n = read(); n1 = read(); n2 = read(); m = read(); for (i = 1; i <= n1; i++) A1[i] = read(); int Ans = 0; for (i = 1; i <= n2; i++) if ((x = read()) >= 1) m -= x - 1; if (n > m) return (void) puts("0"); for (i = 1; i <= n1; i++) if (A1[i] <= 0) return (void) puts("0"); for (i = 0; i < (1 << n1); i++) { int cnt = m, tot = 0; for (j = 0; j < n1; j++) if ((i >> j) & 1) cnt -= A1[j + 1], tot++; int tmp = C(cnt - 1, n - 1); if (tot & 1) Ans = (Ans - tmp + PYZ) % PYZ; else (Ans += tmp) %= PYZ; } printf("%d\n", Ans);}int main() { int T = read(); PYZ = read(); init(); while (T--) work(); return 0;}
阅读全文
0 0
- [BZOJ3129][SDOI2013]方程(扩展Lucas定理+容斥)
- [bzoj3129][SDOI2013]方程
- BZOJ3129: [Sdoi2013]方程
- hdu3929 容斥+扩展Lucas定理
- HDU_5794_ASimpleChess(Lucas定理&&(容斥||dp))
- bzoj 3129 [Sdoi2013]方程 数论 容斥
- hdu5794 lucas定理+容斥
- HDU 5794 A Simple Chess (容斥+Lucas定理)
- bzoj 3129: [Sdoi2013]方程(容斥原理+组合数学+数论)
- Lucas定理与扩展Lucas
- hdu3439 Lucas定理扩展
- 扩展Lucas定理
- lucas定理及扩展lucas定理
- [BZOJ2142]礼物(扩展Lucas定理+中国剩余定理)
- cf 258 E - Devu and Flowers 容斥+组合数取模(lucas定理)
- 【HDOJ 5794】A Simple Chess(大组合数Lucas定理+容斥)
- bzoj 1272: [BeiJingWc2008]Gate Of Babylon (容斥原理+Lucas定理)
- hdu 3929 Big Coefficients(Lucas定理+容斥原理)
- for循环语句(阶乘运算)
- android学习笔记之ImageView的scaleType属性
- hello world
- SDUT 2128 树结构练习——排序二叉树的中序遍历
- CopyOnWriteArrayList解析
- [BZOJ3129][SDOI2013]方程(扩展Lucas定理+容斥)
- Eclipse导入包
- 九九乘法表
- TabLayout的属性
- 时间定时服务
- Construct2功能实现の简单介绍
- Python合并Excel表格(自动合并)
- 分析并写出下列程序的运行结果
- mybatis绑定错误-- Invalid bound statement (not found)