题目链接

题意:

给你A, B, C, D, p, n这些条件

通过公式

请你推出第n项答案(mod1e9+7)

题解: 有前面几项推出后一项的公式一般都是用矩阵快速幂来求, 主要是p/n难以进行操作,那么我们便根据p/n的值来进行分块

例如 p = 16  n = 55

分块可分为 :

p/3 = 5          3

p/4 = 4          4

p/5 = 3          5

p/6 = 2          6 , 7 , 8

p/9 = 1          9 , 10 , 11, 12, 13, 14, 15, 16 

p/17 = 0       17 ........55 

以此类推在这些区间内的p/i的值不变

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int mod = 1e9+7;
int A, B, C, D, n, p;

struct Matrix{
	int t[3][3];
	Matrix(){
		memset(t, 0, sizeof(t));//初始化都为0 
	}
}mat; 

Matrix operator * (Matrix aa, Matrix bb){//定义矩阵相乘 
	Matrix cc;
	for(int i = 0; i < 3; i++){
		for(int j = 0; j < 3; j++){
			ll ans = 0;
			for(int k = 0; k < 3; k++){
				ans += (ll)aa.t[i][k]*bb.t[k][j];
			}
			cc.t[i][j] = ans%mod;
		}
	}
	return cc; 
}

Matrix QuickPow(Matrix aa, int b){//快速幂 
	Matrix cc = mat;
	while(b){
		if(b&1){
			cc = cc*aa;
		}
		aa = aa*aa;
		b>>=1;
	}
	return cc;
}
 
int main() {
	mat.t[0][0] = mat.t[1][1] = mat.t[2][2] = 1;
		/**
		1 0 0
		0 1 0
		0 0 1
		矩阵快速幂所用的单位矩阵 
		**/
	int t;
	scanf("%d", &t);
	while(t--){
		scanf("%d%d%d%d%d%d",&A, &B, &C, &D, &p, &n);
		if(n == 1){
			printf("%d\n",A);
			continue;
		}
		Matrix f;
		f.t[0][0] = D;//   D C 0 
		f.t[0][1] = C;//   1 0 0 
		f.t[1][0] = 1;//   0 0 1
		f.t[2][2] = 1;
		int flag = 0;
		
		for(int i = 3; i <= n;){
			if(p/i == 0){//当i > p 时,p/i = 0 
				Matrix w = f;
				w = QuickPow(w, n-i+1);
				printf("%d\n",(w.t[0][0]*(ll)B+w.t[0][1]*(ll)A+w.t[0][2])%mod);
				flag = 1;
				break;
			}
			int j = min(n, p/(p/i));//分块 
			Matrix w = f;
			/**
			D C p/i       B       B*D+A*C+p/i
			1 0 0     *   A   =   B
			0 0 1         1       1
			**/
			w.t[0][2] = p/i;//在这个区间内 p/i的值不会变 
			w = QuickPow(w, j-i+1);
			ll a = (w.t[1][0]*(ll)B + w.t[1][1]*(ll)A + w.t[1][2]) % mod;
			ll b = (w.t[0][0]*(ll)B + w.t[0][1]*(ll)A + w.t[0][2]) % mod;
			A = a;
			B = b;
			i = j+1;
		}
		if(flag){
			continue;
		}
		printf("%d\n", B); 
	}
	return 0;
}