【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. c# create html table test

    string html = "<html><head><title>44444444</title>"; html += @&quo ...

  2. Spring Boot 2.0 版的开源项目云收藏来了!

    给大家聊一聊云收藏从 Spring Boot 1.0 升级到 2.0 所踩的坑 先给大家晒一下云收藏的几个数据,作为一个 Spring Boot 的开源项目(https://github.com/cl ...

  3. (8)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- Ocelot网关(Api GateWay)

    说到现在现有微服务的几点不足: 1) 对于在微服务体系中.和 Consul 通讯的微服务来讲,使用服务名即可访问.但是对于手 机.web 端等外部访问者仍然需要和 N 多服务器交互,需要记忆他们的服务 ...

  4. 详解javascript中this的工作原理

    在 JavaScript 中 this 常常指向方法调用的对象,但有些时候并不是这样的,本文将详细解读在不同的情况下 this 的指向. 一.指向 window: 在全局中使用 this,它将会指向全 ...

  5. 网络流第一题!!!BZOJ1001

    歇逼了一晚上,懵懵懂懂的懂了Dinic算法 大概是一遍BFS+DFS,还不是很懂,明天继续看!!! #include<iostream> #include<stdio.h> # ...

  6. Promise 原理

    异步:可同时好几件事,互不影响: 同步:按循序一件一件.... 异步好多缺点:.... promise就是解决异步计算的这些缺点的,主要用于: 1.异步计算: 2.可以将异步操作队列化  按期望的顺序 ...

  7. Individual Project - Word frequency program——12061154Joy

    Description&Requirement: http://www.cnblogs.com/jiel/p/3978727.html 项目时间估计 理解项目要求: 1h 构建项目逻辑: 1h ...

  8. first time to use github

    first time to use github and feeling good. 学习软件工程,老师要求我们用这个软件管理自己的代码,网站是全英的,软件也简单易用,方便 https://githu ...

  9. SQL之SELECT语句执行顺序及子句功能

    1.select 语句的执行顺序 SELECT a.id,a.`product_name`,a.`agreement_copies` i,b.id as statusId from `opmp_pro ...

  10. mysql数据库忘记密码时如何修改

    工具/原料 mysql数据库 cmd命令行 打开mysql.exe和mysqld.exe所在的文件夹,复制路径地址 打开cmd命令提示符,进入上一步mysql.exe所在的文件夹