【日常学习】【组合数取模Lucas定理】HDU3037 Saving Beans题解

限时加码!20+主流AI编程工具免费用 购周边加赠Coding Plan Lite,Claude Code、Cursor等即刻畅享,学习进阶更高效! 阅读详情

【提前声明:此题没有通过!WA!有待进一步研究修改。放在这里只是起一个例子的作用,其实这道题鄙人并没有真正掌握= =】、

【本文努力抄袭模仿了小花妹妹的博文0戳我0)】

  • 题目大意:共T个测试点,每个测试点中,给定n、m,求将不超过m个种子放入n个坑的方案总数,最后答案对质数p取模。(一共m个,每个坑放多少无所谓,最后没放完m个也无所谓)

  • 数据范围:1 <= n, m <= 1000000000, 1 < p < 100000。

  • 思路:原题意即求方程x1+…+xn=m解的个数,因为中间的每一项均可为0,故两面同时将加上n,转换成为x1+…+xn+n=m+n,即x1’+…+xn’=m+n,其中每一项至少为1,则由隔板法可知,解的个数为C(n+m-1,m),这只是恰好为m个的方案数,总数为ans=C(n-1,0)+C(n,1)+…+C(n+m-1,m)=C(n+m,m)。(注意,这里组合数的意思表示为:n+m选m个)

  • 知识储备:

    • (A * B) mod C = (A mod C) * (B mod C) mod C
    • Lucas定理:记Lucas(n,m,p)=C(n,m) mod p,则Lucas(n,m,p)=C(n%p,m%p)*Lucas(n/p,m/p,p)。
    • 乘法逆元:假如p是质数,且a、p互质,那么a的(p-1)次方除以p的余数恒为1,那么a和a^(p-2)互为乘法逆元,则(b / a) = (b * a^(p-2) ) mod p。
  • 注意:中途必须强制转换类型,否则出错。【但没有人知道为什么而且最后还是挂了】

鄙人代码:


//HDU3037 Saving Beans Lucas¶¨Àí×éºÏÊýȡģ 
//copyright by ametake

#include<iostream>
using namespace std;

typedef long long ll;

ll t,n,m,p;

ll multi(ll a,ll b)
{
	ll ans=1;
	while (b>0)
	{
		if (b & 1 == 1) ans=((ll)ans*(ll)a)%p;
		a =( (ll)a * (ll)a ) % p;
		b =(ll)(b << 1); 
	}
	return ans;
}

ll c(ll n,ll m)
{
	ll a=1,b=1;
	if (m>n) return 0;
    while (m)
    {
    	a=(a*n)%p;
    	b=(b*m)%p;
    	m--;
    	n--;
    	
	}
	return ((ll)a*(ll)multi(b,p-2))%p;
}

ll lucas(ll n,ll m,ll p)
{
	if ( !m ) return 1;
	else return ( (ll)lucas(n/p,m/p,p)*(ll)c(n%p,m%p)&p);
}

int main()
{
	cin>>t;
	for (ll i=1;i<=t;i++)
	{
		cin>>n>>m>>p;
		cout<<lucas(n+m,m,p)<<endl;
	}
	return 0;
}
 

由于各种时间紧迫,悲剧的用了自带代码粘贴 各种悲剧 下次再改改吧

下一站就要转战DP海洋了···挣扎的小鱼啊···

但无论如何古诗词是不能少的 


——凄凉别后两应同,最是不胜清怨月明中。

hdu3037组合数(Lucas定理) 题目相当于求n个数的和不超过m的方案数。 如果和恰好等于m,那么就等价于方程x1+x2+...+xn = m的解的个数,利用插板法可以得到方案数为: (m+1)*(m+2)...(m+n-1)  = C(m+n-1,n-1) = C(m+n-1,m) 现在就需要求不大于m的,相当于对i = 0,1...,m对C(n+i-1,i)求和,根据公式C(n,k) = C(n-1,k)+C(n-1,k 阅读详情

相关推荐

日常学习】【区间DP+高精】codevs1166 矩阵数游戏题解

题目来自NOIP2007TG3 如果在考场上我现在已经歇菜了吧 今天一整天的时间全部投在这道题上,收获不小。 先上题目 题目描述 Description 【问题描述】 帅帅经常跟同学玩一个矩阵数游戏:对于一个给定的n*m 的矩阵,矩阵中的每个元素aij均 为非负整数。游戏规则如下: 1. 每次数时须从每行各走一个元素,共n个。m次后完矩阵所有

西家家 6564

UVa1336修缮长城

思路 要想最终代价最低,就不能跳跃着修复,也就是经过一段时间后已经修复好的破损应是一段连续区间。 每次只有两个决策:向左走或者向右走。根据这个可以设计出状态: dp(i,j,k)表示修好(i,j)后机器人停留在k(0表示在左端,1表示在右端)端的费用。 另外, c 值的总和是固定的费用,不论决策如何,最终都是要加的。因此不用加入状态转移。不过最后不要忘了加上它 修复某处破损的代价虽然不是定值,但...

CY05627的博客 375

ST-LINK调试STM32H743必看:CubeMX工程中缺失的这行代码导致程序跑飞

本文深入剖析了使用ST-LINK调试STM32H743时,因CubeMX工程中缺失电源电压档位配置代码而导致程序跑飞或出现“Can not access memory”错误的问题。文章解释了H7系列电源与时钟耦合的核心原理,提供了具体的代码修复方案和系统化的调试排查思路,帮助开发者从根本上解决这一常见调试困境。

weixin_29191669的博客 261

Fixing the Great Wall UVA - 1336(区间dp+前缀和)

题目连接;点击打开链接 题目大意:给出n个坏掉的东西的坐标,和 初始花费,以及增长速度,给出机器人的速度和初始坐标,问最少花费能修好全部东西。 题目思路:很容易知道机器人修理好的东西一定是一个连续的区间,并且每一次都会有不同的决策们很容易知道是dp,我们定义状态dp[i][j]为修理好了i到j需要的最少花费, 接下来很容易发现还需要知道机器人在区间的哪一端,所以我们定义状态dp[i][j

w571523631的博客 335

uva1336

这题相当于二分法,就两个决策,向左向右,关于费用计算要注意,作者是每次都把所有点的总费用累积到状态值中。 #include<iostream> #include<algorithm> #include<math.h> #include<string.h> #include<stdio.h> #include<string>...

timeruler的博客 275

poj 2777 Count Color

题意:一个长为L的板,分为L份

A Cube Master 553

UVA 1336 Fixing the Great Wall(区间DP)

题意:修长城n个损坏点

glq007的acm的奋斗 1582

UVA 1336 Fixing the Great Wall - ACM/ICPC CERC 2004

#include&lt;bits/stdc++.h&gt; using namespace std; double v,kase,vis[1010][1010][2],f[1010][1010][2]; int n; struct node{ double l,tt,pl; }a[1010]; double add(int i,int j){ return a[j].l-a[i-1].l; }...

Napoleon2004的博客 335

UVa #1336 Fixing the Great Wall (例题9-21)

这道题的动态规划部分还比较直观: 每次只有两个决策:向左走或者向右走。根据这个可以设计出状态:d(i,j,k)表示区间 [i,j] 已经被修复,目前处于最左端(k=0)或最右端(k=1)。 另外, c 值的总和是固定的,不论决策如何,最终都是一样的。因此不用加入状态转移。不过最后不要忘了加上它; 因此只用考虑 delta 就可以了。每次转移的代价就是区间 [i,j] 以外的所

专攻挖掘机炒鸡蛋算法的专栏 2241

UVA1336(区间dp)

区间dp给我的印象一直是O(n3)的 做到这题才发现自己理解的偏差 题解参考:原作者 #include &lt;iostream&gt; #include &lt;algorithm&gt; #include &lt;queue&gt; #include &lt;stack&gt; #include &lt;cstdio&gt; #include &lt;string&gt; #in...

yxmGo 253

uva1632Alibaba

题目描述: Alibaba the famous character of our childhood stories would like to be immortal in order to keep bringing happiness to children. In order to rich this status he needs to prove that he is still

fouzhe的博客 1081

Uva1336 修长城 【有关未来费用的区间dp】

题外话此题简化版:codevs1258/洛谷P1220 此题(伪)升级版:送披萨(可以选择送给这个人或者不送) 题目大意中的题目背景属于报复行为,大家无视即可。题目大意邪恶的魔王jyf用厉害的膜法在长城上制造了n个破坏点,正义的守护者boshi此时正处于x处,他急忙准备去修复长城。对于每个破坏点,boshi站在这个破坏点前面,然后用修复膜法瞬间修复,但是需要花费一些体力,并且由于jyf的膜法狠厉

litble的成(tui)长(fei)史 760

UVA1336FixingTheGreatWall

用区间来dp,这回也算是长见识了。因为我们可以向左或向右决策,所以用一个区间加移动方向即可表示状态。

qq_16603365的博客 412

poj2777

大二时层接触过线段树,知道大概是什么样子,会写最简单的那种,比如区间最值,区间和,但也是局限在一个点更新的情况下,现在接触到了lazy思想,我认为lazy思想才是线段树的精华吧,而且不是那么好理解。 首先说下,复杂度的问题,因为一条任意的线段最多被分解为2logn个线段,所以我们查询的复杂度是logn,更新一个点的时候,我们其实也就是做树高的复杂度就好了,所以也是logn,但是如果是多个点一起更

斑驳记忆的专栏 991

hdu-3037-组合数-Lucas定理

http://acm.hdu.edu.cn/showproblem.php?pid=3037 题意很简单 求C(n+m,m)%p,P是小于1e5的素数 n,m《1e18 那么得到         #include #include #include #include #include #include #include #inclu

缺氧 1148

uva 1336 修长城 动态规划

dynamic(i, j, k)中i代表已修好的部分的左端点,j代表已修好的部分的右端点, k==0代表此时机器人在i点, k==1代表此时机器人在j点。如果k = 0, 那么机器人一定是修好i+1到j的所有点,再到i点修好了i点处的缺口,所以k=0时的转移方程为dynamic(i, j, 0) = min(dynamic(i+1, j, 0) + 代价, dynamic(i+1, j, 1) +...

GaoJieVery6 330

uva 1336 - Fixing the Great Wall 修缮长城

比较难想的动态规划 uva 1336 - Fixing the Great Wall 修缮长城

便纵有千种风情 933

poj 2777 Count Color 【线段树lazy区间染色 + 查询区间颜色数目 + 状态压缩】

Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 39950   Accepted: 12050 Description Chosen Problem Solving and Program design as an optional cour

世界很大 1383

UVA1336 - Fixing the Great Wall

区间DP

ACoder 401

poj2777 Count Color

线段树+位运算,思路好

AaronPolaris 1150
上一篇: 【日常学习】乘法逆元&&欧拉定理&&费马小定理&&欧拉函数应用&&常大学霸
下一篇: 【日常学习】【棋盘DP】codevs1267 老鼠的旅行题解
ametake
博客等级 码龄12年 36粉丝 153原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值