BZOJ_3129_[Sdoi2013]方程_组合数学+容斥原理

Description

给定方程
    X1+X2+. +Xn=M
我们对第l..N1个变量进行一些限制:
Xl < = A
X2 < = A2
Xn1 < = An1
我们对第n1 + 1..n1+n2个变量进行一些限制:
Xn1+l > = An1+1
Xn1+2 > = An1+2
Xnl+n2 > = Anl+n2
求:在满足这些限制的前提下,该方程正整数解的个数。
答案可能很大,请输出对p取模后的答案,也即答案除以p的余数。

Input

输入含有多组数据,第一行两个正整数T,p。T表示这个测试点内的数据组数,p的含义见题目描述。
    对于每组数据,第一行四个非负整数n,n1,n2,m。
    第二行nl+n2个正整数,表示A1..n1+n2。请注意,如果n1+n2等于0,那么这一行会成为一个空行。

Output

共T行,每行一个正整数表示取模后的答案。

Sample Input

3 10007
3 1 1 6
3 3
3 0 0 5

3 1 1 3
3 3

Sample Output

3
6
0

【样例说明】
对于第一组数据,三组解为(1,3,2),(1,4,1),(2,3,1)
对于第二组数据,六组解为(1,1,3),(1,2,2),(1,3,1),(2,1,2),(2,2,1),(3,1,1)

HINT

n < = 10^9  , n1 < = 8   , n2 < = 8   ,  m < = 10^9  ,p<=437367875

对于l00%的测试数据:  T < = 5,1 < = A1..n1_n2  < = m,n1+n2 < = n


如果没有限制,方程解的个数就是$m$个球$(n-1)$个板不能为空的方案数即$C(m-1,n-1)$。

现在有了两个限制,但第二个限制可以直接在$m$上进行处理对于$A_i$,从$m$中减掉$A_i-1$即可。

第一个限制特别少,我们可以容斥一下。

转化成求总方案数-有一个不满足的方案数+有两个不满足的方案数.......

不满足的方案数也是在$m$上进行处理。

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
using namespace std;
typedef long long ll;
int n,n_1,n_2,m,A[100];
ll mods[100050],ks[100050],MOD,fac[100050];
ll qp(ll x,ll y,ll mod) {
ll re=1;for(;y;y>>=1ll,x=x*x%mod) if(y&1ll) re=re*x%mod; return re;
}
void exgcd(ll a,ll b,ll &x,ll &y,ll &p) {
if(!b) {p=a; x=1; y=0; return ;}
exgcd(b,a%b,y,x,p); y-=a/b*x;
}
ll INV(ll a,ll b) {
ll x,y,d;
exgcd(a,b,x,y,d);
return d==1?(x%b+b)%b:-1;
}
ll Fac(ll x,ll p,ll pk) {
if(!x) return 1;
return qp(fac[pk],x/pk,pk)*fac[x%pk]%pk*Fac(x/p,p,pk)%pk;
}
ll C(ll x,ll y,ll p,ll pk) {
if(x<y) return 0;
ll i,re=0;
for(i=x;i;i/=p) re+=i/p;
for(i=y;i;i/=p) re-=i/p;
for(i=x-y;i;i/=p) re-=i/p;
re=qp(p,re,pk);
if(!re) return 0;
for(fac[0]=1,i=1;i<=pk;i++) fac[i]=i%p?fac[i-1]*i%pk:fac[i-1];
return re*Fac(x,p,pk)%pk*INV(Fac(y,p,pk),pk)%pk*INV(Fac(x-y,p,pk),pk)%pk;
}
ll crt(ll x,ll y) {
ll ans=0;int i;
for(i=1;i<=mods[0];i++) {
ll Mi=MOD/ks[i],Ai=C(x,y,mods[i],ks[i]),Ti=INV(Mi,ks[i]);
ans=(ans+Mi*Ai%MOD*Ti%MOD)%MOD;
}
return ans;
}
void solve() {
int mask=(1<<(n_1))-1;
int i,j;
ll ans=0;
for(i=n_1+1;i<=n_1+n_2;i++) {
m-=(A[i]-1);
}
//printf("m=%d\n",m);
for(i=0;i<=mask;i++) {
ll re=0;
int cnt=0;
for(j=1;j<=n_1;j++) {
if(i&(1<<j-1)) {
cnt++; re+=(A[j]);
}
}
//printf("cnt=%d,i=%d,%lld %lld\n",cnt,i,m-re-1,n-1);
ll tmp=crt(m-re-1,n-1);
if(cnt&1) {
ans=(ans-tmp+MOD)%MOD;
}else {
ans=(ans+tmp)%MOD;
}
}
printf("%lld\n",ans);
}
int main() {
int T;
scanf("%d%lld",&T,&MOD);
int i; ll j=MOD;
for(i=2;1ll*i*i<=j;i++) {
if(j%i==0) {
mods[++mods[0]]=i; ks[mods[0]]=1;
while(j%i==0) j/=i,ks[mods[0]]*=i;
}
}
if(j!=1) mods[++mods[0]]=ks[mods[0]]=j;
while(T--) {
scanf("%d%d%d%d",&n,&n_1,&n_2,&m);
for(i=1;i<=n_1+n_2;i++) {
scanf("%d",&A[i]);
}
solve();
}
}

BZOJ_3129_[Sdoi2013]方程_组合数学+容斥原理的更多相关文章

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

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

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

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

  3. BZOJ_3398_[Usaco2009 Feb]Bullcow 牡牛和牝牛_组合数学

    BZOJ_3398_[Usaco2009 Feb]Bullcow 牡牛和牝牛_组合数学 Description     约翰要带N(1≤N≤100000)只牛去参加集会里的展示活动,这些牛可以是牡牛, ...

  4. BZOJ_4517_[Sdoi2016]排列计数_组合数学

    BZOJ_4517_[Sdoi2016]排列计数_组合数学 Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[ ...

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

    [BZOJ3129][SDOI2013]方程(容斥,拓展卢卡斯定理) 题面 BZOJ 洛谷 题解 因为答案是正整数,所先给每个位置都放一个就行了,然后\(A\)都要减一. 大于的限制和没有的区别不大, ...

  6. HDU.1796 How many integers can you find ( 组合数学 容斥原理 二进制枚举)

    HDU.1796 How many integers can you find ( 组合数学 容斥原理 二进制枚举) 题意分析 求在[1,n-1]中,m个整数的倍数共有多少个 与 UVA.10325 ...

  7. UVA.10325 The Lottery (组合数学 容斥原理 二进制枚举)

    UVA.10325 The Lottery (组合数学 容斥原理) 题意分析 首先给出一个数n,然后给出m个数字(m<=15),在[1-n]之间,依次删除给出m个数字的倍数,求最后在[1-n]之 ...

  8. UVA.11806 Cheerleaders (组合数学 容斥原理 二进制枚举)

    UVA.11806 Cheerleaders (组合数学 容斥原理 二进制枚举) 题意分析 给出n*m的矩形格子,给出k个点,每个格子里面可以放一个点.现在要求格子的最外围一圈的每行每列,至少要放一个 ...

  9. BZOJ_3124_[Sdoi2013]直径_树形DP

    BZOJ_3124_[Sdoi2013]直径_树形DP Description 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵 ...

随机推荐

  1. Angular v6 正式发布

    Angular 6 正式发布 Angular 6 已经正式发布了!这个主要版本并不关注于底层的框架,更多地关注于工具链,以及使 Angular 在未来更容易快速推进. 作为发布的一部分,我们同步了主要 ...

  2. java 如何使的float保留2位或者多位小数 (转载)

    转载自 http://blog.csdn.net/com_stu_zhang/article/details/7214565 方法1: float   f   =  34.232323;    Big ...

  3. iOS 博客资源精选

    摘要:记录一些网上非常牛的人写的博文.收藏起来. 以备日后需要时学习备用. 1:iOS中UIWebView的Javascript与Objective-C通信 http://imchao.net/201 ...

  4. Spring结合log4j(slf4j)

    maven依赖         <!-- slf4j (级联:log4j/slf4j-api) --> <dependency>         <groupId> ...

  5. Android官方开发文档下载

    Android官方开发文档 docs-24_r02.rar(链接:https://pan.baidu.com/s/12xC998JeUHj3ndfDXPM2ww 密码:bxyk) ADT下载.Andr ...

  6. Java并发之ReentrantLock

    一.ReentrantLock简介 ReentrantLock字面意义上理解为可重入锁.那么怎么理解可重入这个概念呢?或者说和我们经常用的synchronized又什么区别呢? ReentrantLo ...

  7. 进阶-MongoDB 知识梳理

    MongoDB 一.MongoDB简介 MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种.它在许多场景下可用于替代传统的关系型数据库或键/值存储方式.Mo ...

  8. js基础进阶--关于Array.prototype.slice.call(arguments) 的思考

    欢迎访问我的个人博客:http://www.xiaolongwu.cn Array.prototype.slice.call(arguments)的作用为:强制转化arguments为数组格式,一般出 ...

  9. Spring Boot全局支持CORS(跨源请求)的配置方法

    http://blog.csdn.net/zhangchao19890805/article/details/53893735

  10. mysql读写分离总结

    随着一个网站的业务不断扩展,数据不断增加,数据库的压力也会越来越大,对数据库或者SQL的基本优化可能达不到最终的效果,我们可以采用读写分离的策略来改变现状.读写分离现在被大量应用于很多大型网站,这个技 ...