思路:根据题目可以知道,兴奋度只跟相邻的两位有关,因此剩下的位置我们就有
m
n
−
2
m^{n-2}
mn−2种方法,然后对于这两位,前一位的选择对后一位产生贡献,比如这一位选择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}
mn−2 * (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;
}