转自

[林夕-梦](https://www.cnblogs.com/cmmdc/p/6936196.html)

因此,这里附上一道题:

https://vjudge.net/contest/446582#problem/F

这道题运用了矩阵快速幂和数论分块。

双倍经验:
1.把变量改为常量(如mod)程序效率大大提高!
2.矩阵快速幂的常数如何处理。

问题:如何求前n项f(i)[1,n]的和?

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const long long mod=1e9+7;
ll A,B,C,D,p;
struct Matrix {
	ll m[5][5]; int h,l;
}d,nw,One;
Matrix Mul(Matrix a,Matrix b) {
	Matrix tmp=nw;
	for(int i=1;i<=a.h;i++) {
		for(int j=1;j<=b.l;j++) {
			for(int k=1;k<=a.l;k++) {
				tmp.m[i][j]+=a.m[i][k]*b.m[k][j]%mod;
				tmp.m[i][j]%=mod;
			}
		}
	}
	tmp.h=a.h,tmp.l=b.l;
	return tmp;
}

Matrix Quick_pow(int b) {
	Matrix mul=One;
	for(;b;b>>=1,d=Mul(d,d)) if(b&1)mul=Mul(mul,d);
	return mul;
}
void init() {
	for(int i=1;i<=3;i++) for(int j=1;j<=3;j++)nw.m[i][j]=0;
	One.h=One.l=3;
	for(int i=1;i<=3;i++) {
		for(int j=1;j<=3;j++) {
			if(i==j)One.m[i][j]=1;
			else One.m[i][j]=0;
		}
	}
}
int main() {
	int T;
	ll N;
	init();
	scanf("%d",&T);
	while(T--) {
		scanf("%lld%lld%lld%lld%lld%lld",&A,&B,&C,&D,&p,&N);
		if(N==1) {printf("%lld\n",A);continue;}
		if(N==2) {printf("%lld\n",B);continue;}
		
		Matrix now;
		now.m[1][1]=A,now.m[2][1]=B,now.h=3,now.l=1;
		int L,R;
		for(L=3;L<=N;L=R+1) {
			if(p/L==0) R=N;
			else R=min(p/(p/L),N);
			now.m[3][1]=p/L;
			//
			d.h=d.l=3;
			d.m[1][1]=0,d.m[1][2]=1,d.m[1][3]=0;
			d.m[2][1]=C,d.m[2][2]=D,d.m[2][3]=1;
			d.m[3][1]=0,d.m[3][2]=0,d.m[3][3]=1;
			//
			now=Mul(Quick_pow(R-L+1),now);
		}
		printf("%lld\n",now.m[2][1]);
	}
	return 0;
}