HDU 6395 Sequence

一、題目

點此看題

二、解法

最難處理的是pn\frac{p}{n},由於這個最多隻有根號個取值,我們可以數論分塊,對於每個塊內都跑一邊矩陣加速。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int mod = 1e9+7;
int read()
{	
	int x=0,flag=1;char c;
	while((c=getchar())<'0' || c>'9') if(c=='-') flag=-1;
	while(c>='0' && c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
	return x*flag;
}
int T,a,b,c,d,n,p;
struct Matrix
{
	int a[4][4];
	Matrix() {memset(a,0,sizeof a);}
	void init() {memset(a,0,sizeof a);}
	Matrix operator * (const Matrix &b) const
	{
		Matrix r;
		for(int i=1;i<=3;i++)
			for(int j=1;j<=3;j++)
				for(int k=1;k<=3;k++)
					r.a[i][k]=(r.a[i][k]+1ll*a[i][j]*b.a[j][k])%mod;
		return r;
	}
}A,F;
Matrix qkpow(Matrix a,int b)
{
	Matrix r;
	for(int i=1;i<=3;i++) r.a[i][i]=1;
	while(b>0)
	{
		if(b&1) r=r*a;
		a=a*a;
		b>>=1;
	}
	return r;
}
void work(int w,int t)
{
	A.a[1][3]=t;
	F=qkpow(A,w)*F;
}
signed main()
{
	T=read();
	while(T--)
	{
		A.init();F.init();
		a=read();b=read();c=read();
		d=read();p=read();n=read();
		A.a[1][1]=d;A.a[1][2]=c;
		A.a[2][1]=A.a[3][3]=1;
		F.a[1][1]=b;F.a[2][1]=a;F.a[3][1]=1;
		for(int l=3,r;l<=min(n,p);l=r+1)
		{
			r=min(n,p/(p/l));
			work(r-l+1,p/l);
		}
		if(n>max(p,2)) work(n-max(p,2),0);
		printf("%d\n",F.a[1][1]);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章