(lucas) Saving Beans

题目:

Although winter is far away, squirrels have to work day and night to save beans. They need plenty of food to get through those long cold days. After some time the squirrel family thinks that they have to solve a problem. They suppose that they will save beans in n different trees. However, since the food is not sufficient nowadays, they will get no more than m beans. They want to know that how many ways there are to save no more than m beans (they are the same) in n trees.

Now they turn to you for help, you should give them the answer. The result may be extremely huge; you should output the result modulo p, because squirrels can’t recognize large numbers.
Input
The first line contains one integer T, means the number of cases.

Then followed T lines, each line contains three integers n, m, p, means that squirrels will save no more than m same beans in n different trees, 1 <= n, m <= 1000000000, 1 < p < 100000 and p is guaranteed to be a prime.
Output
You should output the answer modulo p.
Sample Input
2
1 2 5
2 1 5
Sample Output
3
3

Hint
For sample 1, squirrels will put no more than 2 beans in one tree. Since trees are different, we can label them as 1, 2 … and so on.
The 3 ways are: put no beans, put 1 bean in tree 1 and put 2 beans in tree 1. For sample 2, the 3 ways are:
put no beans, put 1 bean in tree 1 and put 1 bean in tree 2.

分析与解答

1.先说一下lucas
参考:https://blog.csdn.net/wyg1997/article/details/52152282
https://blog.csdn.net/wyg1997/article/details/52152282
lucas定理:

(图片来自https://blog.csdn.net/arrowlll/article/details/53064748)
其实我们想一下二进制,111:就是1* 2^0+1*2^1+1*2^2
这个定理也是一样的akak-1…..a1a0就是p进制的每一位
所以有如下解释:

A、B是非负整数,p是质数。AB写成p进制:A=a[n]a[n-1]…a[0],B=b[n]b[n-1]…b[0] 这里的每一个数组元素表示其p进制的每一位。
则组合数C(A,B)=C(a[n],b[n])C(a[n-1],b[n-1])…*C(a[0],b[0])。也就是说,把大组合数问题变成了一个个的小组合数。(A,B小于mod)

其实可以想一下快速幂,里面%2就是取二进制的最后一位数,/2就是二进制向前移动一位,所以怎么实现代码也和快速幂类似,如下:

表达式:C(n,m)%p=C(n/p,m/p)*C(n%p,m%p)%p。(可以递归)
这里如果n/p和m/p很大,我们仍然可去调用lucas
递归方程:(C(n%p, m%p)*Lucas(n/p, m/p))%p。(递归出口为m==0,return 1)

LL Lucas(LL n,LL k)     //Lucas定理递归 
{if (k == 0)     //递归终止条件 return 1;elsereturn C(n % mod , k % mod) * Lucas(n / mod , k / mod) % mod;
}

对于每一个c(n,k)我们要写一个函数也就是求(n! / ( k! * ( n - k)! ) )%mod,由于有除法取模,所以我们要求k!*(n - k)!的逆元。
这里用小费马求逆元,我们还需写一个快速幂。由于组合数里面有阶乘,所以我们还需打一个阶乘表

整体下来就是这个样子
这里对mod取模

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
LL mod = 1000003;
LL fac[1000000+11] = {1,1};
void getfac()       //打一个阶乘表 
{for (int i = 2 ; i <= 1000000 ; i++)fac[i] = fac[i-1] * i % mod;
}
LL quick_mod(LL n , LL m)       //求快速幂 
{LL ans = 1;n %= mod;while (m){if (m & 1)ans = ans * n % mod;n = n * n % mod;m >>= 1;}return ans;
}
LL C(LL n , LL k)       //费马小定理求逆元 
{if (k > n)return 0;elsereturn fac[n] * (quick_mod(fac[k] * fac[n-k] % mod , mod - 2)) % mod;
}
LL Lucas(LL n,LL k)     //Lucas定理递归 
{if (k == 0)     //递归终止条件 return 1;elsereturn C(n % mod , k % mod) * Lucas(n / mod , k / mod) % mod;
}
int main()
{getfac();LL n,k;int Case = 1;int u;scanf ("%d",&u);while (u--){scanf ("%lld %lld",&n,&k);printf ("Case %d: %lld\n",Case++,Lucas(n,k));}return 0;
}

2.再说一下这个题
m个小球放到n个盒子,盒子可以为空, 方案数就是:C(n+m-1,n-1)
这个题是m个果子放到n个树上,类比一下,数就是盒子,小球就是果子,那么方案数就是C(n+m-1,n-1)
现在这个果子可以是0到m个,
所以总方案数
=C(n+m-1,n-1)+C(n+m-2,n-1)+…+C(n+1,n-1)+C(n,n-1)+C(n-1,n-1)
有一个组合数公式c(m,n)=c(m-1,n-1)+c(m-1,n)
这个组合数公式也可以看作:C(m,n-1)+C(m,n)=C(m+1,n)
还有个组合数公式:C(n,n)=1
所以我们从总方案数的后面变形
C(n-1,n-1)=C(n,n)
C(n-1,n-1)+C(n-1,n-1)=C(n,n)+C(n,n-1)=C(n+1,n)
现在后三个
C(n+1,n-1)+C(n,n-1)+C(n-1,n-1)=C(n+1,n-1)+C(n+1,n)=C(n+2,n)
我们发现,C(n+1,n-1)+C(n,n-1)+C(n-1,n-1)
这里m从2到0,上式等于C(n+2,n)
那么我们推广到整个式子
C(n+m-1,n-1)+C(n+m-2,n-1)+…+C(n+1,n-1)+C(n,n-1)+C(n-1,n-1)
这里m从m到0,式子等于C(n+m,n)
推到这我们现在就只需求
C(n+m,m) % p

(我觉得我应该去学数学。。我爱数学啊)
现在这个题p不是固定的每次都会变,所以我们不能用打表了
C(n,m)=n!/(m!(n-m)!)
=(n*(n-1) (n-m+1))/m!
分子从n-0一直到n-(m-1)也就是说循环m-1-0+1次也就是m次,而分母m!从1乘到m也是m次,那么我们就可以每次通过一个循环计算出C(n,m)了

ll C(ll n,ll m,ll p){if(m==0) return 1;if(m>n-m) m=n-m;ll up=1,down=1;for(int i=1;i<=m;i++){//这里不能打表了 up = (up*(n-i+1))%p;down=(down*i)%p; }return up*Pow(down,p-2,p)%p;
}

参考:
https://blog.csdn.net/qq_27717967/article/details/51493877
这个是wrong answer 我也不知道为什么

//当取模的p小于1e9时,不用预处理
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long ll;
//计算n的k次方对M取模,二分法
ll Pow(ll n, ll k, ll p){ll ans=1;while(k){if(k&1)ans=(ans*n)%p;n = (n*n)%p;k>>=1; //k=k>>1  k=k/2;}return ans;
}
ll C(ll n,ll m,ll p){if(m==0) return 1;if(m>n-m) m=n-m;ll up=1,down=1;for(int i=1;i<=m;i++){//这里不能打表了 up = (up*(n-i+1))%p;down=(down*i)%p; }return up*Pow(down,p-2,p)%p;
}
ll lucas(ll n,ll m,ll p){if(m==0) return 1;return C(n%p,m%p,p)*lucas(n/p,m/p,p);
}
int main(){int t=1;ll m,n,p;scanf("%d",&t);while(t--){scanf("%I64d%I64d%I64d",&n,&m,&p);printf("%I64d\n",lucas(n+m,m,p));}return 0;
}

后来改成预处理,lucas也改变,才对。
但是这个代码改到上一个代码的那个题上,就runtime error
我也不知道为什么,玄学就玄学到这了

#include <iostream>
#include <string.h>
#include <cmath>
#define ll long long
using namespace std;
const int maxn=100002;
ll n,m,p;
ll fac[maxn];void getfac(ll p)//预处理阶层
{fac[0]=1;for(int i=1;i<=p;i++)fac[i]=fac[i-1]*i%p;
}ll power(ll a,ll n,ll p)//快速幂运算
{ll ans=1;while(n){if(n&1)ans=ans*a%p;a=a*a%p;n/=2;}return ans;
}ll lucas(ll n,ll m,ll p)
{ll ans=1;while(n&&m){ll a=n%p;ll b=m%p;if(a<b) return 0;ans=(ans*fac[a]*power(fac[b]*fac[a-b]%p,p-2,p))%p;//  fac[b]*fac[a-b]后面别忘了%p,否则WAn/=p;m/=p;}return ans;
}int main()
{int t;cin>>t;while(t--){cin>>n>>m>>p;getfac(p);cout<<lucas(n+m,m,p)<<endl;}return 0;
}

输入数据第一行是一个正整数T,表示数据组数 (T <= 100) 接下来是T组数据,每组数据有3个正整数 n, m, p (1 <= m <= n <= 10^9, m <= 10^4, m < p < 10^9, p是素数)第一个代码对

1 <= n, m <= 1000000000, 1 < p < 100000 and p is guaranteed to be a prime.第二个代码对

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/560670.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(矩阵快速幂)解所有类似Fibonacci 的题目

Description In the Fibonacci integer sequence, F0 0, F1 1, and Fn Fn − 1 Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, … An alternative formula for the Fibonacci sequence is Gi…

php getdbused,PHP之购物车

该文章记录了购物车的实现代码&#xff0c;仅供参考book_sc_fns.phpinclude_once(output_fns.php);include_once(book_fns.php);include_once(db_fns.php);include_once("user_auth_fns.php");include_once("admin_fns.php");include_once("data_vali…

2018.9.15,Arduino—流水灯实验报告

实验任务和目的 通过Arduino控制LED形成流水灯效果 实验条件 Arduino UNO&#xff0c;面包板&#xff0c;6个LED&#xff0c;6个220Ω电阻 实验过程和结果 实验详细步骤&#xff1a; 在各LED正极和Arduino引脚之间串联一个限流电阻&#xff0c;并将LED负极与Arduion的GND相连 …

2018.9.10.Matlab实验一:熟悉Matlab开发环境

一、实验任务和目的 1. 熟悉Matlab的系统环境及基本操作方法。 2. 掌握Matlab的搜索路径及其设置方法。 3. 熟悉Matlab的帮助信息的查阅方法。 二、实验内容 1. 熟悉 Matlab 工作界面的多个常用窗口的及使用方法。 熟悉Command windows、Workspace、Command history、C…

2018.9.10.Matlab实验二:Matlab基本运算

实验二&#xff1a;Matlab基本运算 一、实验任务和目的 1. 掌握变量的定义与数据类型。 2. 掌握变量的初始化方法。 3. 掌握数组、多维数组与子数组的定义、存储、赋值、变换。 4. 掌握逻辑数组的用法。 5. 熟悉MATLAB常用的函数、常用标点和快捷键。 二、实验内容 1. …

2018.9.15,Matlab实验三:字符串、单元数组和结构体

一、实验任务和目的 掌握Matlab的字符串常用函数及其操作方法。掌握Matlab的结构体的基本操作方法。掌握Matlab的元胞数组的基本操作方法。 二、实验内容字符串数组Str[‘hopes, dreams, hold up, old up’]&#xff0c;查找’O’出现的次数和位置。现有三个字符串变量s1“i”…

c++ 不能分配给为0的数组_【嵌入式C】你有想过quot;数组下标quot;为何从0开始吗?...

1、聊一聊相信大家都有看过电影&#xff0c;今天所分享的是其经典背景音乐&#xff0c;或许音乐响起你又会想起那条单纯、善良的秋田犬&#xff01;今天跟大家聊聊一个有意思的话题&#xff0c;C中的数组下标为啥是从0开始?或者说为什么现在大部分的编程语言都会选择从0开始索…

2018.9.19.Matlab实验四:Matlab程序设计

一、实验任务和目的 熟悉程序设计思想。掌握伪代码的编写方法。掌握分支语句和循环结构的用法。 二、实验内容 输入一个百分制成绩&#xff0c;要求输出成绩等级A、B、C、D、E&#xff0c;其中90-100为A&#xff0c;80-89为B&#xff0c;70-79为C&#xff0c;60-69为D&#…

sata接口 图解 定义_SATA协议简介

SATA协议简介1、概述本文档主要介绍SATA的发展历程以及SATA相关协议&#xff0c;为后续SATA驱动框架分析做基础知识准备。2、SATA简介2.1 SATA发展历程2.1.1 PATA硬盘PATA硬盘叫做并行ATA硬盘(Parellel ATA)。为了限制其信号放大系统产生的高噪声&#xff0c;常采用高达5V的电压…

30岁软件测试转产品_SENSORO 产品总监回特入选 2019 年福布斯中国 30 岁以下精英榜...

日前&#xff0c;福布斯中国发布 2019 年度 30 岁以下精英榜&#xff08;30 Under 30&#xff09;&#xff0c;SENSORO&#xff08;北京升哲科技有限公司&#xff09;产品总监回特 成功入选 U30 精英榜企业科技版块。福布斯中国表示&#xff0c;今年技术领域人才辈出&#xff0…

pagehelper插件oracle,带你学习最简单的分页插件PageHelper

引言:PageHelper是国内非常优秀的一款开源的mybatis分页插件&#xff0c;它支持基本主流与常用的数据库&#xff0c; 例如mysql、 oracle、mariaDB、 DB2、 SQLite、Hsqldb等。今天墨白就给大家聊聊PageHelper这款分页插件,下面是PageHelper开源地址,感兴趣的小伙伴可以去看一下…

实验5matlab自定义函数的编写

问题 自定义一个函数&#xff0c;求给定复数的指数、对数、正弦和余弦&#xff0c;并在命令文件中调用该函数。自定义一个函数&#xff0c;计算一行向量中各元素的均值和标准差。求下列方程的根&#xff1a; f(z)exx2xx100.f(z) \ e^{x}x^{2}x^{\sqrt {x}}100\,. f(z) exx2xx…

ic读卡器设置工具_从Matlab被禁来看,给IC教育带来哪些启发?

在上周五看到朋友圈转发包云岗老师就Matlab被禁后在某论坛的发言&#xff0c;在阅读的当时就很有感触&#xff0c;本想当晚就写点东西&#xff0c;不曾想拖到了现在。包老师的梳理的几个点&#xff0c;是结合教学和应用来谈的。在IC教育培训方面&#xff0c;我对这些观点也深以…

arduino光敏+LED+数码管+蜂鸣器综合实验

内容 用光敏控制LED的明暗程度&#xff0c;光敏值在3位数码管上显示&#xff0c;串口输出光敏值&#xff0c;蜂鸣器到一定的值会didi 话不多说&#xff0c;直接上代码&#xff0c;那几个部分拼到一起&#xff0c;多了个数的拆分&#xff0c;让k1k2k3分别等于百位十位个位 代…

server sql 水平分表_springboot集成Shardingsphere进行分库分表

当公司业务量上去之后&#xff0c;单表支撑不了的时候&#xff0c;分库分表就是一个绕不开的话题&#xff0c;小弟最近新入职一家公司&#xff0c;发现这边公司在用ShardingSphere来进行分库分表&#xff0c;之前没接触过这方面&#xff0c;所以就写了个demo学习一下&#xff0…

网鼎杯2020php反序列化,2020-网鼎杯(青龙组)_Web题目 AreUserialz Writeup

0x02 AreUSerialz关于s大写小写问题&#xff0c;可以看p神在圈子里发的&#xff0c;我在最后付上截图考点: php反序列化 php特性 利用链构造1.打开页面得到代码如下:include("flag.php");highlight_file(__FILE__);class FileHandler {protected $op;protected $file…

利用matlab绘制图形

目前存在的一些问题&#xff1a; 1.第一题的两个图像无法重叠 2.最后一个题的第一个图是六瓣&#xff0c;而我写的是八瓣 感谢张同学给我指出来&#xff0c;目前我正在思考解决方法 第一个的话我以为把框缩小就可以重叠了&#xff0c;但是今天试了一下还是分开的&#xff0c;还…

matlab guide对话框+滑动条+弹出式菜单+列表框的使用

文章目录前言matlab数据传递概观对话框创建利用滑动条实现颜色调控利用弹出式菜单选择并输入文本框利用列表框选择并输入文本框前言 我觉得gui无非就是给程序加了件衣服&#xff0c;其实具体的程序我们都会写&#xff0c;我们唯一不明白的是那几个部分数据之间的传递&#xff…

流放之路材质过滤怎么设置_松下除湿机怎么样 松下除湿机款式有哪些型号【详解】...

马上南方就要进入梅雨季节了&#xff0c;潮湿的天气容易滋生细菌&#xff0c;可能会导致人们出现过敏现象&#xff0c;所以很多家庭都选择购买除湿机&#xff0c;现在市场上的除湿机不是很多&#xff0c;其中松下的除湿机比较受欢迎&#xff0c;所以小编我就来跟大家说一说松下…