K(K>=3)个猿辅导的老师们在玩一个击鼓传花的小游戏。每击一次鼓,拿着花的老师要将花交给别人,不能留在自己手中。游戏开始前花在小猿手中,求击了N次鼓后,这朵花又回到小猿手中的方案数,请输出这个数模1000000007后的结果。
输入两个数N,K。
20%的数据:(3<=K<=10, 1<= N<=10)
70%的数据:(3<=K<=1000, 1<= N<=1000)
100%的数据:(3<=K<=10^9, 1<= N<=10^9)
输出方案数模1000000007后的结果
3 3
2
#include<iostream>
#include<vector>
using namespace std;
int main()
{
long long n, k;
cin >> n >> k;
if (k < 3)return 0;
vector<vector<long long>>dp(n + 1, vector<long long>(k + 1));
dp[0][0] = 1;
dp[0][1] = 0;
for (long long i = 1; i <= n; i++)
{
dp[i][0] = dp[i - 1][1] % 1000000007;
dp[i][1] = (dp[i - 1][0] * (k - 1)) % 1000000007 + (dp[i - 1][1] * (k - 2)) % 1000000007;
}
cout << dp[n][0] << endl;
system("pause");
return 0;
} #include <bits/stdc++.h>
#define int long long
using namespace std;
const int MODN=1000000007;
vector<vector<int>> mul(vector<vector<int>> &a,vector<vector<int>> &b){
vector<vector<int>> ret(2,vector<int>(2,0));
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
ret[i][j]+=a[i][k]*b[k][j],ret[i][j]%=MODN;
return ret;
}
vector<vector<int>> quick_pow(vector<vector<int>> & mat,int n){
vector<vector<int>> ret = {{1,0},{0,1}};
while(n){
if(n&1)ret=mul(ret,mat);
mat=mul(mat,mat);
n>>=1;
}
return ret;
}
int32_t main(){
int n,k;cin>>n>>k;
if(n==1)cout<<0<<endl;
else if(n==2)cout<<k-1<<endl;
else{
vector<vector<int>> mat={{k-2,k-1},{1,0}};
mat=quick_pow(mat,n-2);
int ret=0;
vector<int> mv={k-1,0};
for(int i=0;i<2;i++)ret+=mat[0][i]*mv[i],ret%=MODN;
cout<<ret<<endl;
}
return 0;
} import java.util.*;
public class Main{
public static void main(String[] args){
Scanner input;
int N, K;
input = new Scanner(System.in);
while(input.hasNext()){
N = input.nextInt();
K = input.nextInt();
System.out.println(new Main().Solution(N, K));
}
}
private long Solution(int N, int K){
int M;
long[][] A, An;
M = 1000000007;
if(N == 1)
return 0;
if(N == 2)
return K - 1;
A = new long[][]{{K - 2, 1}, {K - 1, 0}};
An = pow(A, N - 2);
return An[0][0] * (K - 1) % M;
}
private long[][] pow(long[][] A, int n){
Stack<Integer> stack;
long[][] ans;
stack = new Stack<>();
ans = new long[][]{{1, 0}, {0, 1}};
while(n > 0){
stack.push(n % 2);
n /= 2;
}
while(!stack.isEmpty()){
multi(ans, ans);
if(stack.pop() == 1)
multi(ans, A);
}
return ans;
}
private void multi(long[][] A, long[][] B){
long a00, a01, a10, a11;
int M;
M = 1000000007;
a00 = (A[0][0] * B[0][0] + A[0][1] * B[1][0]) % M;
a01 = (A[0][0] * B[0][1] + A[0][1] * B[1][1]) % M;
a10 = (A[1][0] * B[0][0] + A[1][1] * B[1][0]) % M;
a11 = (A[1][0] * B[0][1] + A[1][1] * B[1][1]) % M;
A[0][0] = a00;
A[0][1] = a01;
A[1][0] = a10;
A[1][1] = a11;
}
} 坑点在取模,乘法套加法的别乱取模,如
通过画一棵树分析,如1的子节点可以有2,3,4...,找出规律,除了
之外,另一部分为首项是
,公差是
的等比数列,根据
的奇偶性来决定加上还是减去这一部分,于是式子可以化简为
,又
, 于是
#include <bits/stdc++.h>
using namespace std;
long long p = 1000000007;
long long quick_pow(long long a, long long b) {
long long ans = 1;
while(b) {
if(b & 1)ans = ans * a % p;
a = a * a % p;
b >>= 1;
}
return ans;
}
int main() {
long long n, k;
cin >> n >> k;
if(n == 1) {
cout << 0 << endl;
return 0;
} else if(n == 2) {
cout << k - 1 << endl;
return 0;
}
long long ans = 0;
long long odd = n % 2 == 1 ? -1 : 1; //(-1)^n
ans = ((k - 1) * (quick_pow(k - 1, n - 1) + odd)) % p;//(k-1)*[(k-1)^(n-1)+(-1)^n]
ans = ans * quick_pow(k, p - 2);
ans %= p;
cout << ans << endl;
return 0;
}
import java.util.Scanner;
import java.lang.Math;
public class Main{
public static void main(String[] args)
{
int s=1000000007;
Scanner sc=new Scanner(System.in);
int k=sc.nextInt();
int n=sc.nextInt();
long[] f=new long[n+3];
f[2]=k-1;f[1]=0;
long sum=(k-1);
for(int i=3;i<=n;i++)
{
sum=sum*(k-1); //k=951 n=223
f[i]=(sum-f[i-1])%s;
sum=sum%s;
}
System.out.print(f[n]>=0?f[n]:f[n]+s);
}
} import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static final int mod=1000000007;
public static void main(String[] args) {
Scanner sin=new Scanner(System.in);
while(sin.hasNext()){
int n=sin.nextInt();
int k=sin.nextInt();
System.out.println(calcu(n,k));
}
}
public static long calcu(int n,int k){
//求dp[n][0]的方案数
long[][] dp=new long[n][k];
Arrays.fill(dp[0],1L);
dp[0][0]=0;
for(int i=1;i<n;i++){
long sum=0;
for(long num:dp[i-1]) sum+=num;
for(int j=0;j<k;j++){
dp[i][j]=sum-dp[i-1][j];
while(dp[i][j]>mod){
dp[i][j]%=mod;
}
}
}
return dp[n-1][0];
}
} 70%通过率,100%的是数学家吧
def mul2Matrix(x,y):
# 二维矩阵相乘的实现
ans = [[0 for i in range(2)]for j in range(2)]
for i in range(2):
for j in range(2):
for k in range(2):
ans[i][j] += (x[i][k]% 1000000007) * (y[k][j] % 1000000007)
return ans
def mul1Matrix(x,y):
# 二维矩阵与size为(2*1)的矩阵相乘
ans = [[0] for j in range(2)]
for i in range(2):
for k in range(2):
ans[i][0] += (x[i][k]% 1000000007) * (y[k][0]% 1000000007)
return ans
def quickMatrix(m,n):
# 矩阵快速幂运算实现
E = [[0 for i in range(2)]for j in range(2)]
for i in range(2):
E[i][i] = 1
while(n):
if n % 2 != 0:
E = mul2Matrix(E,m)
m = mul2Matrix(m,m)
n >>= 1
return E
if __name__ == '__main__':
n, k = map(int, input().split())
m = [[k-2,k-1],[1,0]]
x = [[k-1],[0]]
# 注意考虑特殊情况,若不加此条件,只能通过90%的case
if n >= 2:
tmp = quickMatrix(m, n-2)
print(mul1Matrix(tmp,x)[0][0]%1000000007)
else:
print(0) n, k = map(int, input().split()) lis = [0] for i in range(1,n): lis.append((k-1)**i-lis[i-1]) print(lis[-1]%1000000007)