【BZOJ3129】[SDOI2013]方程(容斥,拓展卢卡斯定理)

题面

BZOJ

洛谷

题解

因为答案是正整数,所先给每个位置都放一个就行了,然后\(A\)都要减一。

大于的限制和没有的区别不大,提前给他\(A_i\)个就好了。

假如没有小于的限制的话,那么就是经典的隔板法直接算答案。

如果提前给完之后,还剩\(M\)个球,要放进\(n\)个盒子,答案就是\(\displaystyle{M+n-1\choose n-1}\)

然而有一个小于的限制很烦人。发现数量很少,那么直接爆枚子集,强制一些不合法,然后容斥计算答案即可。

模数蛋疼无比,需要\(exLucas\)。

\(exLucas\)的时候因为模数相同,所以可以提前预处理模每个质因子情况下的阶乘,这样会快很多。

#include<iostream>
#include<cstdio>
using namespace std;
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int fpow(int a,int b)
{
int s=1;
while(b){if(b&1)s*=a;a*=a;b>>=1;}
return s;
}
int fpow(int a,int b,int MOD)
{
int s=1;
while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}
return s;
}
void exgcd(int a,int b,int &x,int &y)
{
if(!b){x=1;y=0;return;}
exgcd(b,a%b,y,x);y-=a/b*x;
}
int inv(int n,int m)
{
int x,y;exgcd(n,m,x,y);
x=(x%m+m)%m;return x;
}
int fac[50],pw[50],tot=0;
int jc[50][11000];
int JC(int n,int p,int MOD,int id,int &z)
{
if(!n){z=0;return 1;}
int ret=JC(n/p,p,MOD,id,z);z+=n/p;
if(n>MOD)ret=1ll*ret*fpow(jc[id][MOD],n/MOD,MOD)%MOD,n%=MOD;
ret=1ll*ret*jc[id][n]%MOD;
return ret;
}
int exLucas(int n,int m,int P)
{
if(n<0||m<0||n<m)return 0;
int M[50],V[50];
for(int i=1;i<=tot;++i)
{
int MOD=fpow(fac[i],pw[i]),zero=0,a=1,b=1,z;
a=JC(n,fac[i],MOD,i,z);zero+=z;
b=JC(m,fac[i],MOD,i,z);zero-=z;
b=1ll*b*JC(n-m,fac[i],MOD,i,z)%MOD;zero-=z;
V[i]=1ll*a*inv(b,MOD)%MOD*fpow(fac[i],zero,MOD)%MOD;
M[i]=MOD;
}
for(int i=2;i<=tot;++i)
{
int x,y;exgcd(M[1],M[i],x,y);
x=(1ll*x*(V[i]-V[1])%M[i]+M[i])%M[i];
V[1]=(1ll*M[1]*x+V[1])%(M[1]*M[i]);
M[1]*=M[i];
}
return V[1];
}
int n,n1,n2,m;
int A[20];
int main()
{
int T=read(),P=read(),MOD=P;
for(int i=2;i*i<=P;++i)
if(P%i==0)
{
fac[++tot]=i;pw[tot]=0;
while(P%i==0)++pw[tot],P/=i;
}
if(P>1)++tot,fac[tot]=P,pw[tot]=1;
for(int i=1;i<=tot;++i)
{
int MOD=fpow(fac[i],pw[i]);
jc[i][0]=1;
for(int j=1;j<=MOD;++j)jc[i][j]=1ll*jc[i][j-1]*((j%fac[i])?j:1)%MOD;
}
while(T--)
{
n=read();n1=read();n2=read();m=read()-n;
for(int i=1;i<=n1+n2;++i)A[i]=read()-1;
for(int i=1;i<=n2;++i)m-=A[n1+i];
int S=1<<n1,ans=0;
for(int i=0;i<S;++i)
{
int N=m,opt=1;
for(int j=0;j<n1;++j)
if(i&(1<<j))opt=MOD-opt,N-=A[j+1]+1;
ans=(ans+1ll*opt*exLucas(N+n-1,n-1,MOD))%MOD;
}
printf("%d\n",ans);
}
return 0;
}

【BZOJ3129】[SDOI2013]方程(容斥,拓展卢卡斯定理)的更多相关文章

  1. 【BZOJ4830】[HNOI2017]抛硬币(组合计数,拓展卢卡斯定理)

    [BZOJ4830][HNOI2017]抛硬币(组合计数,拓展卢卡斯定理) 题面 BZOJ 洛谷 题解 暴力是啥? 枚举\(A\)的次数和\(B\)的次数,然后直接组合数算就好了:\(\display ...

  2. 【BZOJ2142】礼物(拓展卢卡斯定理)

    [BZOJ2142]礼物(拓展卢卡斯定理) 题面 BZOJ 洛谷 题解 显然如果\(\sum w_i>n\)无解. 否则答案就是:\(\displaystyle \prod_{i=1}^m{n- ...

  3. bzoj3129[Sdoi2013]方程 exlucas+容斥原理

    3129: [Sdoi2013]方程 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 582  Solved: 338[Submit][Status][ ...

  4. bzoj3198[Sdoi2013]spring 容斥+hash

    3198: [Sdoi2013]spring Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1143  Solved: 366[Submit][Sta ...

  5. BZOJ3129 SDOI2013方程(容斥原理+扩展lucas)

    没有限制的话算一个组合数就好了.对于不小于某个数的限制可以直接减掉,而不大于某个数的限制很容易想到容斥,枚举哪些超过限制即可. 一般情况下n.m.p都是1e9级别的组合数没办法算.不过可以发现模数已经 ...

  6. bzoj千题计划267:bzoj3129: [Sdoi2013]方程

    http://www.lydsy.com/JudgeOnline/problem.php?id=3129 如果没有Ai的限制,就是隔板法,C(m-1,n-1) >=Ai 的限制:m减去Ai &l ...

  7. BZOJ3129 [Sdoi2013]方程 【扩展Lucas】

    题目 给定方程 X1+X2+. +Xn=M 我们对第l..N1个变量进行一些限制: Xl < = A X2 < = A2 Xn1 < = An1 我们对第n1 + 1..n1+n2个 ...

  8. 洛谷 P4336 黑暗前的幻想乡 —— 容斥+矩阵树定理

    题目:https://www.luogu.org/problemnew/show/P4336 当作考试题了,然而没想出来,呵呵. 其实不是二分图完美匹配方案数,而是矩阵树定理+容斥... 就是先放上所 ...

  9. [SDOI2013]泉(容斥)

    /* 容斥加上哈希 首先我们可以2 ^ 6枚举相同情况, 然后对于这些确定的位置哈希一下统计方案数 这样我们就统计出了这些不同方案的情况, 然后容斥一下就好了 */ #include<cstdi ...

随机推荐

  1. angularjs的$window功能小练习

    我们想在一个文本框输入一些文字,然后点击铵钮,alert()出来. <div ng-app="alertApp" ng-controller="alertContr ...

  2. loj6062 pair

    直接套用霍尔定理. 由于A有多个选择,考虑维护B是否合法. 首先B数组的顺序显然是没有用的,可以直接排序. 然后每个A就都变成了向一个后缀连边. 对于B,原本需要check每一个集合是否满足|u|&l ...

  3. 【调试技巧】 Fiddler高级用法之url映射请求

    问题场景: 已发布线上APP出现接口错误,如何测试线上APP访问本地请求? 已发布线上H5页面,静态资源或js调试,如何映射本地js? 一般解决方案: 猜测(一般明显问题). 找到原发布包,修改请求资 ...

  4. Quartz.Net分布式任务管理平台(续)

           感谢@Taking园友得建议,我这边确实多做了一步上传,导致后面还需处理同步上传到其他服务器来支持分布式得操作.所有才有了上篇文章得完善. 首先看一下新的项目结构图: 这个图和上篇文章中 ...

  5. Quartz_配置

    quartz_jobs.xml job 任务 其实就是1.x版本中的<job-detail>,这个节点是用来定义每个具体的任务的,多个任务请创建多个job节点即可 name(必填) 任务名 ...

  6. Eddy's mistakes HDU

    链接 [http://acm.hdu.edu.cn/showproblem.php?pid=1161] 题意 把字符串中大写字母变为小写 . 分析 主要是含有空格的字符串如何读入,用getline(c ...

  7. 《linux内核设计与实现》第三章

    1.进程 进程就是正在执行的程序代码的实时结果,不仅包含可执行代码,还包括其他资源,比如:打开的文件,挂起的信号,内核内部数据结构,处理器状态,一个或多个具有内存映射的内存地址空间及一个或多个执行线程 ...

  8. 【转】STM32 独立看门狗简介

    STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效. 看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路就是为了避免这种 ...

  9. vue-devtools 的安装和使用

    vue-devtools的安装与使用 一.在github上下载压缩包,github下载地址:https://github.com/vuejs/vue-devtools 二.解压到本地的某盘 三.用你的 ...

  10. [转帖]紫光展锐5G芯片

    紫光展锐5G芯片已流片:7nm工艺 2019年问世   https://news.mydrivers.com/1/612/612346.htm 本文转载自超能网,其他媒体转载需经超能网同意 高通骁龙X ...