bzoj3129[Sdoi2013]方程 exlucas+容斥原理
3129: [Sdoi2013]方程
Time Limit: 30 Sec Memory Limit: 256 MB
Submit: 582 Solved: 338
[Submit][Status][Discuss]
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
exlucas+容斥啊。
这道题主要考点是exlucas而不是容斥吧。
模型转换可以看成向盒子里装小球 ,转化成隔板原理
而由于组合数C(n,m)中n和m太大了且p不一定是质数,需要用exlucas来求组合数模
对于有下界限制的,强行先分给它 下界-1个
对于上界限制的直接容斥 没超的-至少1个超的+至少2个超的..
exlucas可以翻翻网上博客,主要就用了CRT和快速求阶乘来得到组合数
代码我懒得写了,复制了别人的
lucas&&exlucas https://www.cnblogs.com/candy99/p/6637629.html
这道题代码原网址:http://blog.csdn.net/werkeytom_ftd/article/details/50152143
#include<cstdio>
#include<iostream>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
ll f[10],a[20],b[20],c[20],d[20],e[20],pri[32000+10],fac[100000+10];
bool bz[32000+10];
ll i,j,k,l,t,n,m,n1,n2,ca,p,pp,num,top,xx,yy,cnt;
ll quicksortmi(ll x,ll y,ll p){
if (!y) return 1;
if (y==1) return x%p;
ll t=quicksortmi(x,y/2,p);
t=t*t%p;
if (y%2) t=t*(x%p)%p;
return t;
}
void gcd(ll a,ll b){
if (!b){
xx=1;
yy=0;
}
else{
gcd(b,a%b);
swap(xx,yy);
yy-=xx*(a/b);
}
}
ll getny(ll x,ll y){
gcd(x,y);
xx=(xx%y+y)%y;
return xx;
}
ll calcfac(ll n,ll p,ll pp){
if (n<pp) return fac[n];
ll t=quicksortmi(fac[p-1],n/p,p);
t=t*fac[n%p]%p;
cnt+=n/pp;
t=t*calcfac(n/pp,p,pp)%p;
return t;
}
ll calc(ll x,ll y,ll p,ll pp){
ll i;
fac[0]=1;
fo(i,1,p-1)
if (i%pp==0) fac[i]=fac[i-1];
else fac[i]=fac[i-1]*i%p;
cnt=0;
ll A=calcfac(y,p,pp);
ll tot=cnt;
cnt=0;
ll B=calcfac(x,p,pp);
B=B*calcfac(y-x,p,pp)%p;
B=getny(B,p);
return A*B%p*quicksortmi(pp,tot-cnt,p)%p;
}
ll comb(ll x,ll y,ll p){
if (x>y) return 0;
fo(i,1,top) a[i]=calc(x,y,d[i],e[i]);
fo(i,1,top) b[i]=getny(c[i],d[i]);
ll t=0;
fo(i,1,top) t=(t+a[i]*b[i]%p*c[i]%p)%p;
return t;
}
void dfs(ll x,ll m,ll cnt){
if (x==n1+1){
ll t=comb(n-1,m-1,p);
if (cnt%2) num=((num-t)%p+p)%p;
else num=(num+t)%p;
return;
}
dfs(x+1,m,cnt);
if (m-f[x]) dfs(x+1,m-f[x],cnt+1);
}
int main(){
fo(i,2,32000){
if (!bz[i]) pri[++k]=i;
fo(j,1,k){
if (pri[j]*i>32000) break;
bz[i*pri[j]]=1;
if (i%pri[j]==0) break;
}
}
scanf("%lld%lld",&ca,&p);
pp=p;
fo(i,1,k){
if (pp%pri[i]==0){
d[++top]=1;e[top]=pri[i];
while (pp%pri[i]==0){
d[top]*=pri[i];
pp/=pri[i];
}
}
}
fo(i,1,top) c[i]=p/d[i];
while (ca--){
scanf("%lld%lld%lld%lld",&n,&n1,&n2,&m);
fo(i,1,n1) scanf("%lld",&f[i]);
fo(i,1,n2){
scanf("%lld",&k);
if (k) m-=k-1;
}
num=0;
dfs(1,m,0);
printf("%lld\n",num);
}
}
bzoj3129[Sdoi2013]方程 exlucas+容斥原理的更多相关文章
- BZOJ3129 SDOI2013方程(容斥原理+扩展lucas)
没有限制的话算一个组合数就好了.对于不小于某个数的限制可以直接减掉,而不大于某个数的限制很容易想到容斥,枚举哪些超过限制即可. 一般情况下n.m.p都是1e9级别的组合数没办法算.不过可以发现模数已经 ...
- bzoj千题计划267:bzoj3129: [Sdoi2013]方程
http://www.lydsy.com/JudgeOnline/problem.php?id=3129 如果没有Ai的限制,就是隔板法,C(m-1,n-1) >=Ai 的限制:m减去Ai &l ...
- BZOJ3129 [Sdoi2013]方程 【扩展Lucas】
题目 给定方程 X1+X2+. +Xn=M 我们对第l..N1个变量进行一些限制: Xl < = A X2 < = A2 Xn1 < = An1 我们对第n1 + 1..n1+n2个 ...
- BZOJ3129: [Sdoi2013]方程
拓展Lucas+容斥原理 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cs ...
- 洛谷$P$3301 $[SDOI2013]$方程 $exLucas$+容斥
正解:$exLucas$+容斥 解题报告: 传送门! 在做了一定的容斥的题之后再看到这种题自然而然就应该想到容斥,,,? 没错这题确实就是容斥,和这题有点儿像 注意下的是这里的大于和小于条件处理方式不 ...
- 【BZOJ3129】[SDOI2013]方程(容斥,拓展卢卡斯定理)
[BZOJ3129][SDOI2013]方程(容斥,拓展卢卡斯定理) 题面 BZOJ 洛谷 题解 因为答案是正整数,所先给每个位置都放一个就行了,然后\(A\)都要减一. 大于的限制和没有的区别不大, ...
- BZOJ_3129_[Sdoi2013]方程_组合数学+容斥原理
BZOJ_3129_[Sdoi2013]方程_组合数学+容斥原理 Description 给定方程 X1+X2+. +Xn=M 我们对第l..N1个变量进行一些限制: Xl < = A ...
- [SDOI2013]方程
...最近考了一道数学题.是典型的隔板问题. P.S.最近八中oj上面没有系统地刷过题 题面可以直接转化为m个球分到n个箱子,每个箱子至少放1个,前n1个箱子的球数必须满足全部小于等于A[i],接着n ...
- [BZOJ 3129] [Sdoi2013] 方程 【容斥+组合数取模+中国剩余定理】
题目链接:BZOJ - 3129 题目分析 使用隔板法的思想,如果没有任何限制条件,那么方案数就是 C(m - 1, n - 1). 如果有一个限制条件是 xi >= Ai ,那么我们就可以将 ...
随机推荐
- vue内置指令详解——小白速会
指令 (Directives) 是带有 v- 前缀的特殊属性,职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM. 内置指令 1.v-bind:响应并更新DOM特性:例如:v-bi ...
- 【nodejs】安装browser-sync 遇到错误提示
首先我用的是mac电脑在我执行安装browser-sync时遇到如下问题: 因为不被允许所以我只能不安装全局了: 但是又出现了如下的新问题 纠结了半个小时,终于知道为什么会出现这个问题了, node只 ...
- SpringMVC 无法访问到指定jsp页面可能的原因
当出现你的程序可以访问到对应的controller层.但是却无法访问对应的jsp文件时.你首先做的不是检查web.xml等配置文件,而是打开的服务器根文件检查对应路径下的文件是否存在.命名是否正确.命 ...
- 儿童节,我们从零开始——Python入门资源推荐
原创 2017-06-01 玄魂工作室 玄魂工作室 今天是六一儿童节,首先祝所有的小朋友身体健康,能永远生活在一个没有战争,没有压迫的世界里,永远快乐. 上一篇文章,很多人都对Python的各种书籍感 ...
- split 过滤空的元素
命令形式: split(str='',number=string.count(str))[n] str 分隔符 number 切分几次,[n] 获取第几个值. 1.如果切分的可迭代对象中包含空元素的解 ...
- Mego开发文档 - 保存关系数据
保存关系数据 由于没有对象的更改跟踪,因此关系的操作需要开发者明确指定,在成功执行后Mego会影响到相应的关系属性中. 添加关系 在以下示例中如果成功执行则source的Customer属性会变为ta ...
- linux下的Shell编程(7)使用-x和-n调试shell程序
我们也可以在Shell下调试Shell Script脚本,当然最简单的方法就是用echo输出查看变量取值了.Bash也提供了真正的调试方法,就是执行脚本的时候用-x参数. sh -x filename ...
- python入门(3)python的解释器
python入门(3)python的解释器 Python写的程序是以.py为扩展名的文本文件.要运行代码,就需要Python解释器去执行.py文件. 由于整个Python语言从规范到解释器都是开源的, ...
- 阿里云API网关(1)服务网关的产品概述
网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...
- Lumen框架搭建指南
新人从java转php,到新公司搭建lumen框架,lumen官方文档的坑不是一般的多,对新手极其不友好,记录下我搭建过程,希望对小白们有所帮助. 首先看下官方文档:https://lumen.lar ...