BZOJ3129/洛谷P3301方程(SDOI2013)容斥原理+扩展Lucas定理
题意:给定方程x1+x2+....xn=m,每个x是正整数。但是对前n1个数做了限制x1<=a1,x2<=a2...xn1<=an1,同时对第n1+1到n1+n2个数也做了限制xn1+1>=an1+1....xn1+n2>=an1+n2,输出方程解个数。
解法:首先如果对数字没有任何要求(应该是只要求是非负数)的话,答案就是C(n+m+1,m+1)原理是隔板法。但是此题有各种限制,我们想办法解决限制使得答案往无限制上面靠。
首先是解决要正整数,那么每个数字减一即可,就是m-=n。
然后对于n1+1到n1+n2的限制,大于等于的限制也简单,也是xi>=ai的话就使xi-=ai即可。
好了到最麻烦的xi<=ai限制,这个限制我们没办法通过数字处理来解决。但是我们观察到这些限制个数小于等于8个,自然会想到容斥原理。
那么容斥原理常规套路,无限制-至少一个突破限制(也就是xi>ai为突破限制)方案数+至少两个数字突破限制.........
ok,解题思路就是上面这些。但是这题比较麻烦的在于:要计算的组合数非常大且模数不为质数!!!那么Lucas定理也不管用了,我们只能用到exLucas定理。
推荐看这篇博客:https://www.cnblogs.com/candy99/p/6637629.html
直接套上大佬的exLucas会TLE,有一些地方需要优化,①Lucas函数内每次都要找MOD的因子太慢了,先预处理出来。②Fac函数内每次暴力计算阶乘太慢了,需要在调用Fac之前即C函数处先预处理阶乘。
此题代码(注释的是修改大佬模板地方,加上优化):
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- const int N=1e5+;
- ll n,m,n1,n2,MOD,a[N];
- ll tot=,f[N],c[N];
- ll fac[N];
- void Initfac(ll p,ll pr) { //预处理阶乘
- fac[]=;
- for(ll i=;i<=pr;i++)
- if(i%p) fac[i]=fac[i-]*i%pr;
- else fac[i]=fac[i-];
- }
- ll Pow(ll a,ll b,ll P){
- ll ans=;
- for(;b;b>>=,a=a*a%P)
- if(b&) ans=ans*a%P;
- return ans;
- }
- void exgcd(ll a,ll b,ll &d,ll &x,ll &y){
- if(b==) d=a,x=,y=;
- else exgcd(b,a%b,d,y,x),y-=(a/b)*x;
- }
- ll Inv(ll a,ll n){
- ll d,x,y;
- exgcd(a,n,d,x,y);
- return d==?(x+n)%n:-;
- }
- ll Fac(ll n,ll p,ll pr){
- if(n==) return ;
- ll re=;
- //for(ll i=2;i<=pr;i++) if(i%p) re=re*i%pr;
- re=fac[pr];
- re=Pow(re,n/pr,pr);
- ll r=n%pr;
- //for(int i=2;i<=r;i++) if(i%p) re=re*i%pr;
- re=re*fac[r]%pr;
- return re*Fac(n/p,p,pr)%pr;
- }
- ll C(ll n,ll m,ll p,ll pr){
- if(n<m) return ;
- Initfac(p,pr); //预处理阶乘
- ll x=Fac(n,p,pr),y=Fac(m,p,pr),z=Fac(n-m,p,pr);
- ll c=;
- for(ll i=n;i;i/=p) c+=i/p;
- for(ll i=m;i;i/=p) c-=i/p;
- for(ll i=n-m;i;i/=p) c-=i/p;
- ll a=x*Inv(y,pr)%pr*Inv(z,pr)%pr*Pow(p,c,pr)%pr;
- return a*(MOD/pr)%MOD*Inv(MOD/pr,pr)%MOD;
- }
- ll Lucas(ll n,ll m){ //exLucas
- ll x=MOD,re=;
- // for(ll i=2;i<=MOD;i++) if(x%i==0){
- // ll pr=1;
- // while(x%i==0) x/=i,pr*=i;
- // re=(re+C(n,m,i,pr))%MOD;
- // }
- for (int i=;i<=tot;i++) re=(re+C(n,m,f[i],c[i]))%MOD;
- return re;
- }
- void prework(ll n) {
- ll t=n;
- for (int i=;(ll)i*i<=n;i++) {
- if (t%i==) {
- tot++; f[tot]=i; c[tot]=;
- while (t%i==) t/=i,c[tot]*=i;
- }
- }
- if (t>) f[++tot]=t,c[tot]=t;
- }
- int main()
- {
- int T; scanf("%d%lld",&T,&MOD);
- prework(MOD);
- while(T--) {
- scanf("%lld%d%d%lld",&n,&n1,&n2,&m);
- for(int i=;i<=n1+n2;i++) scanf("%lld",&a[i]);
- for(int i=;i<=n2;i++) m-=a[n1+i]-;
- m-=n;
- ll ans=;
- for(int i=;i<(<<n1);i++) {
- int tot=;
- ll x=m;
- for(int j=;j<n1;j++)
- if (i&(<<j)) { tot++; x-=a[j+]; }
- if (tot%) ans=(ans-Lucas(x+n-,n-)+MOD)%MOD;
- else ans=(ans+Lucas(x+n-,n-))%MOD;
- }
- printf("%lld\n",ans);
- }
- return ;
- }
记录下大佬的exLucas定理模板:
- ll Pow(ll a,ll b,ll P){
- ll ans=;
- for(;b;b>>=,a=a*a%P)
- if(b&) ans=ans*a%P;
- return ans;
- }
- void exgcd(ll a,ll b,ll &d,ll &x,ll &y){
- if(b==) d=a,x=,y=;
- else exgcd(b,a%b,d,y,x),y-=(a/b)*x;
- }
- ll Inv(ll a,ll n){
- ll d,x,y;
- exgcd(a,n,d,x,y);
- return d==?(x+n)%n:-;
- }
- ll Fac(ll n,ll p,ll pr){
- if(n==) return ;
- ll re=;
- for(ll i=;i<=pr;i++) if(i%p) re=re*i%pr;
- re=Pow(re,n/pr,pr);
- ll r=n%pr;
- for(int i=;i<=r;i++) if(i%p) re=re*i%pr;
- return re*Fac(n/p,p,pr)%pr;
- }
- ll C(ll n,ll m,ll p,ll pr){
- if(n<m) return ;
- ll x=Fac(n,p,pr),y=Fac(m,p,pr),z=Fac(n-m,p,pr);
- ll c=;
- for(ll i=n;i;i/=p) c+=i/p;
- for(ll i=m;i;i/=p) c-=i/p;
- for(ll i=n-m;i;i/=p) c-=i/p;
- ll a=x*Inv(y,pr)%pr*Inv(z,pr)%pr*Pow(p,c,pr)%pr;
- return a*(MOD/pr)%MOD*Inv(MOD/pr,pr)%MOD;
- }
- ll Lucas(ll n,ll m){
- ll x=MOD,re=;
- for(ll i=;i<=MOD;i++) if(x%i==){
- ll pr=;
- while(x%i==) x/=i,pr*=i;
- re=(re+C(n,m,i,pr))%MOD;
- }
- return re;
- }
BZOJ3129/洛谷P3301方程(SDOI2013)容斥原理+扩展Lucas定理的更多相关文章
- BZOJ3129 SDOI2013方程(容斥原理+扩展lucas)
没有限制的话算一个组合数就好了.对于不小于某个数的限制可以直接减掉,而不大于某个数的限制很容易想到容斥,枚举哪些超过限制即可. 一般情况下n.m.p都是1e9级别的组合数没办法算.不过可以发现模数已经 ...
- 题解-洛谷P5410 【模板】扩展 KMP(Z 函数)
题面 洛谷P5410 [模板]扩展 KMP(Z 函数) 给定两个字符串 \(a,b\),要求出两个数组:\(b\) 的 \(z\) 函数数组 \(z\).\(b\) 与 \(a\) 的每一个后缀的 L ...
- 【learning】 扩展lucas定理
首先说下啥是lucas定理: $\binom n m \equiv \binom {n\%P} {m\%P} \times \binom{n/P}{m/P} \pmod P$ 借助这个定理,求$\bi ...
- 2015 ICL, Finals, Div. 1 Ceizenpok’s formula(组合数取模,扩展lucas定理)
J. Ceizenpok’s formula time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- BZOJ - 2142 礼物 (扩展Lucas定理)
扩展Lucas定理模板题(貌似这玩意也只能出模板题了吧~~本菜鸡见识鄙薄,有待指正) 原理: https://blog.csdn.net/hqddm1253679098/article/details ...
- [bzoj2142]礼物(扩展lucas定理+中国剩余定理)
题意:n件礼物,送给m个人,每人的礼物数确定,求方案数. 解题关键:由于模数不是质数,所以由唯一分解定理, $\bmod = p_1^{{k_1}}p_2^{{k_2}}......p_s^{{k_ ...
- Lucas定理和扩展Lucas定理
1.Lucas定理 首先给出式子:\(C_n^m\%p = C_{\lfloor\frac{n}{p}\rfloor}^{\lfloor\frac{m}{p}\rfloor} * C_{n\%p}^{ ...
- Ceizenpok’s formula Gym - 100633J 扩展Lucas定理 + 中国剩余定理
http://codeforces.com/gym/100633/problem/J 其实这个解法不难学的,不需要太多的数学.但是证明的话,我可能给不了严格的证明.可以看看这篇文章 http://ww ...
- [笔记] 扩展Lucas定理
[笔记] 扩展\(Lucas\)定理 \(Lucas\)定理:\(\binom{n}{m} \equiv \binom{n/P}{m/P} \binom{n \% P}{m \% P}\pmod{P} ...
随机推荐
- 安装JDK ,提示 错误1316 指定的账户已存在
基于情况: 安装了一个JDK 后,在文件目录中删除了相关文件,之后再次安装,提示 错误1316 指定的账户已存在 造成原因:安装JDK,相当于安装了一个软件,要使用系统的软件卸载功能卸载,不能只删除 ...
- [CSP-S模拟测试]:环(图论+期望)
题目传送门(内部题79) 输入格式 第一行读入两个整数$n,e$表示节点数及$cwystc$已确定的有向边边数. 接下来$e$行,每行两个整数$x,y$描述$cwystc$确定的边. 输出格式 输出一 ...
- VS 2010内存泄漏检测
控制台程序在启动时调用 _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); 程序正常退出后会打印内存泄漏信息. MFC程序不用 ...
- 阿里云服务器+ubantu+nodejs 服务器基本配置流程
所有步骤在MAC 电脑环境下操作 一.配置环境 1.连接到远程服务器 1.购买阿里云ECS服务器,我选用的 ubantu 14.0.4 (64位),购买的时候输入的密码记录下来,没有设置的话可以随后在 ...
- 虚拟主机支持apk
扩展名中填写.apk MIME类型中填写apk的MIME类型 application/vnd.android.package-archive
- selenium启动firefox打开导入向导问题解决
操作系统:win8-64位 火狐版本:40.0.2 问题描述:selenium启动firefox时,每次启动都提示我导入其他浏览器的页签,如下图所示 解决方法一: 到firefox的profiles. ...
- redis和memcached的对比与选型
相似处: 1:Memcached与Redis都属于内存内.键值数据存储方案.均属于NoSQL家族,而且都基于同样的键值数据模型.双方都选择将全部数据保存在内存当中,这自然也就让它们成为非常理想 ...
- shell脚本一一项目6
主题:获取网卡的流量 ifconfig 查看流量 文件流量数据量 脚本内容 #!/bin/bash#name: mark# check network dev's liuliangnic=$1 ech ...
- js 实现两个小数的相乘、相除功能
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Tensorflow创建和读取17flowers数据集
http://blog.csdn.net/sinat_16823063/article/details/53946549 Tensorflow创建和读取17flowers数据集 标签: tensorf ...