BZOJ 2142 礼物(拓展Lucas,中国剩余定理)【BZOJ修复工程】
整理的算法模板合集: ACM模板
点我看算法全家桶系列!!!
实际上是一个全新的精炼模板整合计划
题目链接
https://hydro.ac/d/bzoj/p/2142
是 hydro 的 BZOJ 修复工程 !(我也去领了一点题慢慢修着玩,这题就是我修的嘿嘿嘿)
题目描述
一年一度的圣诞节快要来到了。每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物。不同的人物在小E心目中的重要性不同,在小E心中分量越重的人,收到的礼物会越多。小E从商店中购买了 nnn 件礼物,打算送给 mmm 个人,其中送给第 iii 个人礼物数量为 wiw_iwi 。请你帮忙计算出送礼物的方案数(两个方案被认为是不同的,当且仅当存在某个人在这两种方案中收到的礼物不同)。由于方案数可能会很大,你只需要输出模 PPP 后的结果。
输入格式
输入的第一行包含一个正整数 PPP ,表示模数;
第二行包含两个整整数 nnn 和 mmm ,分别表示小E从商店购买的礼物数和接受礼物的人数;
以下 mmm 行每行仅包含一个正整数 wiw_iwi ,表示小E要送给第 iii 个人的礼物数量。
输出格式
若不存在可行方案,则输出 “Impossible” ,否则输出一个整数,表示模 PPP 后的方案数。
输入样例
100
4 2
1
2
输出样例
12
数据规模和约定
设 P=p1c1×p2c2×p3c3×⋯×ptctP=p_1^{c_1} \times p_2^{c_2} \times p_3^{c_3} \times \cdots \times p_t ^ {c_t}P=p1c1×p2c2×p3c3×⋯×ptct,pip_ipi 为质数。
对于 100%100\%100% 的数据,1≤n≤1091\le n\le 10^91≤n≤109,1≤m≤51\le m\le 51≤m≤5,1≤pici≤1051\le p_i^{c_i}\le 10^51≤pici≤105。
提示
【样例说明】
下面是对样例111 的说明。
以 /
分割,/
前后分别表示送给第一个人和第二个人的礼物编号。121212 种方案详情如下:
1/23 1/24 1/34
2/13 2/14 2/34
3/12 3/14 3/24
4/12 4/13 4/23
Solution
一共 nnn 个礼物,第 111 个人需要 w1w_1w1 个礼物,方案数为 (w1n)\displaystyle {w_1 \choose n}(nw1),然后对于第二个人,从剩下的 n−w1n-w_1n−w1 个礼物中选出 w2w_2w2 个礼物送给第二个人,方案数为 (w2n−w1)\displaystyle {w_2\choose {n-w_1}}(n−w1w2),一次类推,总方案数根据乘法原理显然为:
∏i=1n(win−∑j=1iwj)modp\prod_{i = 1}^{n} {w_i\choose \displaystyle n-\sum_{j=1}^{i}w_j}\mod p i=1∏n(n−j=1∑iwjwi)modp
考虑如何计算。
由于给定的模数 ppp 不是质数,所以我们需要用拓展Lucas定理计算,然后就是一个拓展lucas的模板题了…
关于拓展Lucas定理:
Code
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 1e4 + 6;
int n, m, s, t, ans;
int primes[maxn], cnt;
bool vis[maxn];
int v[maxn], M;
ll A, B;
int mod;
int w[maxn];
int r[maxn];struct mods
{int c, p;ll pc;
}f[maxn];ll qpow(ll a, ll b, ll mod)
{ll res = 1;while(b) {if(b & 1) res = res * a % mod;a = a * a % mod;b >>= 1;}return res;
}ll exgcd(ll a, ll b, ll &x, ll &y)
{if(b == 0) {x = 1, y = 0;return a;}ll d = exgcd(b, a % b, x, y);ll z = x;x = y;y = z - y * (a / b);return d;
}inline ll inv(ll a, ll p)
{ll x, y;exgcd(a, p, x, y);return (x + p) % p;
}//计算 x! 中除掉 val = prime 后模 p 的值
inline ll cal(ll x, ll val, ll p)
{if(x == 0) return 1;ll res = 1;ll last = x % p;for (int i = 1; i <= p; ++ i) if(i % val) res = res * i % p;res = qpow(res, x / p, p);for (ll i = 1; i <= last; ++ i)if(i % val) res = res * i % p;return res * cal(x / val, val, p) % p;
}inline ll C(ll n, ll m, ll p, ll pc)
{if(m > n) return 0;ll k = 0;ll up = cal(n, p, pc);ll down1 = cal(m, p, pc);ll down2 = cal(n - m, p, pc);for (int i = n; i; i /= p) k += i / p;for (int i = m; i; i /= p) k -= i / p;for (int i = n - m; i; i /= p) k -= i / p; return up * inv(down1, pc) % pc * inv(down2, pc) % pc * qpow(p, k, pc) % pc;
}inline ll CRT(int cnt)
{ll m = mod, M[maxn] = {}, t[maxn] = {}, res = 0;for (int i = 1; i <= cnt; ++ i)M[i] = m / f[i].pc; for (int i = 1; i <= cnt; ++ i) {ll y; exgcd(M[i], f[i].pc, t[i], y); res = (res + r[i] % m * M[i] % m * t[i] % m) % m; }return (res % m + m) % m;
}inline ll exlucas(ll A, ll B)
{memset(f, 0, sizeof f);memset(r, 0, sizeof r);int x = mod, cnt = 0;for (ll i = 2; i * i <= x; ++ i) {if(x % i == 0) {f[ ++ cnt].p = i;f[cnt].pc = 1;while(x % i == 0) {x /= i;f[cnt].c ++ ;f[cnt].pc *= i;} r[cnt] = C(A, B, f[cnt].p, f[cnt].pc);}}if(x > 1) {f[ ++ cnt].p = x;f[cnt].c = 1;f[cnt].pc = x; r[cnt] = C(A, B, f[cnt].p, f[cnt].pc);} return CRT(cnt);
}int main()
{scanf("%d%d%d", &mod, &n, &m);ll sum = 0;for (int i = 1; i <= m; ++ i) {scanf("%d", &w[i]);sum += w[i];}if(sum > n) return 0 * puts("Impossible");ll ans = 1;A = n;for (int i = 1; i <= m; ++ i) {B = w[i];ans = (ans * exlucas(A, B)) % mod;A -= w[i];}printf("%lld\n", ans % mod);return 0;
}
BZOJ 2142 礼物(拓展Lucas,中国剩余定理)【BZOJ修复工程】相关推荐
- [BZOJ]2142 礼物 扩展Lucas
2142: 礼物 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 1788 Solved: 748 [ Submit][ Status][ Di ...
- FJNU2018低程A 逃跑路线(Lucas + 中国剩余定理 + LGV定理)题解
题目描述 n个人在w*h的监狱里面想要逃跑,已知他们的同伙在坐标(bi,h)接应他们,他们现在被关在(ai,1)现在他们必须要到同伙那里才有逃出去的机会,这n个人又很蠢只会从(x,y)->(x+ ...
- BZOJ-1951 古代猪文 (组合数取模Lucas+中国剩余定理+拓展欧几里得+快速幂)...
数论神题了吧算是 1951: [Sdoi2010]古代猪文 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1573 Solved: 650 [Submit ...
- bzoj 2142 礼物
题目大意: $n$件礼物,送给$m$个人,其中送给第$i$个人礼物数量为$w_i$,求送礼物的方案数 思路: 显然答案为$\binom{n}{w_1} \binom{n-w_1}{w_2} \cdot ...
- 礼物(中国剩余定理+拓展gcd求逆元+分治=拓展Lucus)
礼物 题意: 求\[C(n,m)\ \%\ p\] \(n,m,p\le 10^9\),且若\(p=\prod_{i=1}^{k}{p_i}^{c_i}\),则\(\forall i\in [1..k ...
- BZOJ1951 [Sdoi2010]古代猪文 【费马小定理 + Lucas定理 + 中国剩余定理 + 逆元递推 + 扩展欧几里得】...
题目 "在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心--" --选自猪王国民歌 很久很久以前,在山的那 ...
- bzoj 3055礼物运送 floyed + 状压DP
bzoj 3055: 礼物运送 floyed first 设f[i][S]表示取到了S集合中的所有点(不一定是经过的所有点),最后停在了i的最优值. 初始就f[i][{i}] = dis[1][i] ...
- 中国剩余定理及其拓展
中国剩余定理 实质就是解nnn次互质的方程,然后分别乘以他们的取模剩余量,然后相加得到答案,这里就不展开叙述. typedef long long ll; const int N = 1e3 + 10 ...
- 学习拓展中国剩余定理小结
前言 话说中国剩余定理好早就会了,但是一直木有接触过拓展的. 只知道它是个什么东东. 最近似乎需要它了,稍微学了学,似乎还挺简单的. 小结一下~ 简介 中国剩余定理我们都懂吧? 而拓展则是把它后面的模 ...
最新文章
- pytorch系列 -- 9 pytorch nn.init 中实现的初始化函数 uniform, normal, const, Xavier, He initialization...
- 记一次阿里云日志服务配置
- postgresql-9.3.0级联复制搭建及简单配置
- python去重txt文本_Python 文件去重(转载)
- 上海一百多个数据中心每年消耗全市1.6%的电,将优胜劣汰
- Linux下防火墙开放端口
- 云服务器镜像麻烦吗_简单说说云服务器的镜像功能作用
- 【经典回放】多种语言系列数据结构算法:希尔排序
- 1200万的天价离职赔偿!
- java spliterator_java 8 stream中的Spliterator简介
- 为所有北京奥运冠军名字作诗(诗集)
- 解决问题--Maven,IDEA项目External Libraries下只有jdk没有maven依赖
- python3及wxpythonGUI多线程防假死与线程消息传递消息(最新)
- html判断图片资源是否存在,javascript怎么判断图片是否存在?
- 自适应控制——仿真实验一 用李雅普诺夫稳定性理论设计自适应规律
- JAVA 实现《中国象棋》游戏
- 人民币利率互换小幅上行,通胀不乐观致紧缩预期趋浓_183
- Incorrect argument type to variable ‘max_allowed_packet‘解决方法
- 弱占优策略--Weakly Dominant Strategy
- 车载网络结构(车内)-基础概念