牛客竞赛提高组 妞妞的三个盒子

妞妞的三个盒子

题目描述:

妞妞在公园里游玩时捡到了很多小球,而且每个球都不一样。妞妞找遍了全身只发现了3个一样的盒子。她打算把这些小球都装进盒子里(盒子可以为空)。她想知道她总共有多少种放法。

将N个不同的球放到3个相同的盒子里,求放球的方案总数M。 结果可能很大,我们仅要求输出M mod K的结果。 现在,妞妞已经统计出了N<=10的所有情况。见下表:

NM
11
22
35
414
541
6122
7365
81094
93284
109842
输入格式:

两个整数 N,K 表示球的个数。

输出格式:

输出仅包括一行,一个整数 M mod K 。

输入样例:
11 10000
输出样例:
9525
数据范围与提示:

对于40%数据,10<=N<=10,000;对于100%数据,10<=N<=1,000,000,000;
对于 100%数据,K<=100,000。

题解:

看表格是否看到想哭

其实这题可能很多人都可以很快的发现一个规律
当前这个数等于前面那个数 × \times × 3 − - 1

应该也许都看出来了吧

其实大家再把表格里的数都乘 2 2 2 看看
2 2 2 的几次方是否有点关系
3 3 3 的几次方哈

在这里插入图片描述

其实应该都发现了每个对应的 M M M 都是 ( 3 n − 1 + 1 ) ÷ 2 (3^{n-1}+1)\div2 (3n1+1)÷2

然后就可以了呀用个快速幂就搞定了

因为有 ÷   2 \div\ 2 ÷ 2

所以要用逆元

也可以不用逆元把模数乘 2 2 2 即可

来解释一下

有点复杂不解释了

上代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
LL ksm(LL a,int b,int m)
{
	LL ans=1;
	while(b)
	{
		if(b&1)ans=ans*a%m;
		a=a*a%m;
		b>>=1;
	}
	return ans;
}
int main()
{
	freopen("bags.in","r",stdin);
	freopen("bags.out","w",stdout);
	int n,m;
	scanf("%d%d",&n,&m);
	m<<=1;//这里就是乘2,左移应该也许看的懂吧
	printf("%lld",((ksm(3,n-1,m)+1)/2)%m);
	return 0;
}

谢谢观看

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值