当前位置: 首页 > news >正文

xtuoj Candy

题目

思路

通过模3运算我们可以把1~N中的数分成三部分,模三余0,模三余1,模三余2,即3n、3n+1、3n+2这三部分。

题目要求取出来的三个数之和是3的倍数,那么有四种情况,从模三余0的数里面取三个、从模三余1的数里面取三个、从模三余2的数里面取三个以及从模三余0、1、2的数里面分别取一个。

模三余0、1、2的个数分别设为c0、c1、c2。

c0就是满足求1=<3n<=N中,n的个数,n最大取值为N/3,n=1,2,3,...,N/3,一共有N/3个,也就是说c0=N/3;c1就是满足求1=<3n+1<=N中,n的个数,n最大取值为N/3,n=0,1,2,3,...,(N-1)/3,一共有(N-1)/3+1=(N+2)/3个,也就是说c1=(N+2)/3;c2就是满足求1=<3n+2<=N中,n的个数,n最大取值为(N-2)/3,n=1,2,3,...,(N-2)/3,一共有(N-2)/3+1=(N+1)/3个,也就是说c2=(N+1)/3。

然后从n个里面取3个,需要用到组合数,而 \binom{3}{n} = \frac{n*(n-1)*(n-2)}{3*2*1} ,n最大值达到了 ^{10^{6}} ,三个 ^{10^{6}} 相乘,结果可能会溢出,而且还要除以6,可能会有整数除法一些精度的问题,此外题目最后有要求要模1000000007,所以我们为了避免这些问题,不妨在计算组合数的过程中就模1000000007,而模运算不适用于除法,所以我们想要把除法转换为乘法,需要用到逆元,逆元的求法有很多种,可以看我写的其他博客求逆元方法详解-CSDN博客,然后这里我将采用费马小定理这种方法,还需要用到快速幂,然后避免除法还可以避免整数除法精度的问题,岂不妙哉!

当然由于我们只要求一个逆元,所以其实可以先用费马小定理写个代码先求出来,这样我们在计算组合数的时候就可以直接用了,而不用每次求组合数的时候都求一次逆元。

其实也不是非得求逆元,那就把空间设置大一点,然后就用普通的计算方法就好了,但是还是要注意不要把所有方案都加起来之和一起再模,这样可能结果会非常大,应该算一种方案取模后累加起来,再去算另外的方案取模。

代码一

#include <stdio.h>
#define MOD 1000000007
#define ll long long// 计算组合数C(n,3),如果n<3则返回0
ll C(ll n) {if (n < 3) return 0;// 预计算6的逆元(模MOD下),166666668是6在模10^9+7下的逆元ll inv6 = 166666668;return n * (n - 1) % MOD * (n - 2) % MOD * inv6 % MOD;
}int main() {ll N;while (scanf("%lld", &N) && N != 0) {ll c0 = N / 3;                    // 余0的数的个数ll c1 = (N + 2) / 3;              // 余1的数的个数ll c2 = (N + 1) / 3;              // 余2的数的个数ll ans = c0 * c1 % MOD * c2 % MOD; // 情况4:各余数选一个ans = (ans + C(c0)) % MOD;        // 情况1ans = (ans + C(c1)) % MOD;        // 情况2ans = (ans + C(c2)) % MOD;        // 情况3printf("%lld\n", ans);}return 0;
}

代码二

#include <stdio.h>
#define MOD 1000000007
#define ll long longll inv6;// 快速幂计算a^b % MOD
ll pow_mod(ll a, ll b) {ll res = 1;while (b) {if (b & 1) res = res * a % MOD;a = a * a % MOD;b >>= 1;}return res;
}// 计算组合数C(n,3)
ll C(ll n) {if (n < 3) return 0;return n * (n - 1) % MOD * (n - 2) % MOD * inv6 % MOD;
}int main() {ll N;inv6 = pow_mod(6, MOD-2);while (scanf("%lld", &N) && N != 0) {ll c0 = N / 3;ll c1 = (N + 2) / 3;ll c2 = (N + 1) / 3;ll ans = c0 * c1 % MOD * c2 % MOD; // 三种余数各选一个ans = (ans + C(c0)) % MOD;ans = (ans + C(c1)) % MOD;ans = (ans + C(c2)) % MOD;printf("%lld\n", ans);}return 0;
}

代码三

#include <stdio.h>
#define MOD 1000000007
#define ll long longint main() {ll N;while (scanf("%lld", &N) && N != 0) {ll c0 = N / 3;ll c1 = (N + 2) / 3;ll c2 = (N + 1) / 3;// 直接计算所有情况,避免复杂的组合数函数ll ans = 0;// 情况1:三个数都模3余0if (c0 >= 3) ans = (ans + c0 * (c0 - 1) * (c0 - 2) / 6) % MOD;// 情况2:三个数都模3余1if (c1 >= 3) ans = (ans + c1 * (c1 - 1) * (c1 - 2) / 6) % MOD;// 情况3:三个数都模3余2if (c2 >= 3) ans = (ans + c2 * (c2 - 1) * (c2 - 2) / 6) % MOD;// 情况4:三个数余数各不相同ans = (ans + c0 * c1 % MOD * c2 % MOD) % MOD;printf("%lld\n", ans);}return 0;
}

http://www.dtcms.com/a/516982.html

相关文章:

  • 襄阳大摩网站建设网站开发者所有权归属
  • 一条龙网站建设价格编程应用
  • StarsNote 1.1.0测试版
  • Java--网络原理
  • 2025-10-21 XiaoQuQu 的 2025 CSP-S 第二轮模拟 ROUND2 补题
  • react中的受控组件与非受控组件
  • iOS的动态库和静态库的差异区别以及静态库的好处
  • Word文档中打勾和打叉的三种方法
  • 基于微信小程序的高校班务管理系统【2026最新】
  • 编程教学网站推荐网络营销广告策划
  • 网站建设开票属于哪个名称锦州网站建设品牌
  • 基于SAM2的眼动数据跟踪6——SAM2跟踪
  • Factory Boy:Python测试数据生成的优雅方案
  • 网站icp备案团购网站模板下载
  • 肾脏癌症图像分类数据集
  • 亚马逊云渠道商:AWS Lake Formation是什么?
  • 动画网站源码网站搭建 保定
  • 甘肃做网站工信部查网站备案
  • matlab的map函数怎么使用
  • 郴州网站seo外包wordpress+分页静态
  • 网站做的好坏主要看discuz论坛源码
  • 【展厅多媒体】飞屏互动技术如何增强展厅的科技氛围?
  • 25:第3章面向对象(上)作业示例
  • 宸建设计网站百度知道怎么赚钱
  • 专业定制网站公司网络安全专业就业前景
  • 语雀知识库下载工具yuque-dl
  • 网站按钮确定后图片怎么做企业邮箱怎么在手机上登录
  • 芜湖高端网站建设模版网站系统
  • lesson73:Vue渐进式框架的进化之路——组合式API、选项式对比与响应式新范式
  • Vue02-VUE工程化开发模式