气球消消乐
问题描述
蒜头君有 n 只气球,蒜头君把气球排成一排。初始时,气球都是白色,现在蒜头君想用 m 种颜色给气球涂色,如果相邻的气球的颜色相同,这 2 个气球会发生消消乐,蒜头君希望你求出会发生消消乐的涂色方法有多少种。最后答案对 10^9+7取模。
输入格式
输入两个整数n(1<=n<=10 ^ 12),m(1<=m<=10^8)
输出格式
输出一行表示答案。
样例输入
3 4
样例输出
28
这是一题简单的组合排序问题。
题目要求发生消消乐的涂色方法有多少种 ?我们可以求出不发生消消乐的情况数x,用总的情况数y减去x即可。
很明显
x
=
m
∗
(
m
−
1
)
n
−
1
x = m*(m - 1)^{n-1}
x=m∗(m−1)n−1 (第一个有m种涂法,第一个往后每一个有m-1种涂法)。
总数
y
=
m
n
y=m^n
y=mn .
即答案为
m
n
−
m
∗
(
m
−
1
)
n
−
1
m^n- m*(m - 1)^{n-1}
mn−m∗(m−1)n−1
因为n的范围为10^12所以使用快速幂。
最后注意取模的时候 需要加上一个mod,要不然会出现负数的情况。
ans = (pow_mod(m, n, mod) - (m * pow_mod(m - 1, n - 1,mod)) % mod + mod) % mod
#include<iostream>
typedef long long ll;
using namespace std;
const ll mod = 1e9 + 7;
ll pow_mod(ll a, ll n, ll m) { //求a的n次方并对m取模的结果
ll ans = 1;
while(n) {
if (n&1) {
ans = (ans * a) % m;
}
a = (a * a) % m;
n >>= 1;
}
return ans % mod;
}
int main () {
int n, m;
cin >> n >> m;
ll ans = (pow_mod(m, n, mod) - (m * pow_mod(m - 1, n - 1,mod)) % mod + mod) % mod;
cout << ans << endl;
return 0;
}