牛客练习赛76 C-CG的通关秘籍 (组合数学)

这篇博客探讨了一道涉及数学和编程的问题,计算在一定约束条件下进行操作的组合计数。通过使用组合数学的原理和编程技巧,如快速幂运算,博主给出了高效的解决方案。文章介绍了具体的算法思路,包括如何利用相邻元素的关系来简化问题,并通过递推公式求解逆元。最终,给出了C++代码实现,展示了如何计算特定情况下的组合计数结果。
摘要由CSDN通过智能技术生成

在这里插入图片描述
思路:根据题目可以知道,兴奋度只跟相邻的两位有关,因此剩下的位置我们就有 m n − 2 m^{n-2} mn2种方法,然后对于这两位,前一位的选择对后一位产生贡献,比如这一位选择x,那么就有C(x-1,1)中方法加1,C(m-x,1)种方法加2。
然后x属于[1,m]写出来就是3*[ C(1,1)+C(2,1)+C(3,1)+…+C(m-1,1) ],带公式即为3 * C(m,2)。
然后n次操作有n-1对,再乘上n-1。
答案即为 C(m,2) * m n − 2 m^{n-2} mn2 * (n-1) * 3

代码:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN = 1e6 + 7;
const int MOD = 1e9 + 7;

ll q_pow(ll a,ll b){
	ll res = 1;
	while(b){
		if(b &1 ) res = res * a % MOD;
		a = a * a % MOD;
		b >>= 1; 
	}
	return res % MOD;
}

ll fact[MAXN],inv[MAXN],fiv[MAXN],ans[MAXN];
void init(){//线性递推求逆元 
	fact[0] = fact[1] = 1;
	fiv[0] = fiv[1] = 1;
	inv[1] = 1;
	for(int i = 2;i < MAXN;i ++){
		fact[i] = fact[i-1] * i % MOD;
		inv[i] = (MOD-MOD/i) * inv[MOD%i] % MOD;
		fiv[i] =  inv[i] * fiv[i-1] % MOD;
	}
}

ll C(int n,int m){
	if(m > n) return 0;
	return fact[n] * fiv[n-m] % MOD * fiv[m] % MOD;
}

int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		ll n,m;
		scanf("%lld%lld",&n,&m);
		ll res = 3ll * (m-1) * m / 2 % MOD;
        res = res * (n-1) % MOD;
        res = res * q_pow(m,n-2) % MOD;
		printf("%lld\n",res);
	}		
	return 0;
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值