HDU 5895 矩阵快速幂+欧拉函数

Mathematician QSC

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)


Problem Description
QSC dream of becoming a mathematician, he believes that everything in this world has a mathematical law.

Through unremitting efforts, one day he finally found the QSC sequence, it is a very magical sequence, can be calculated by a series of calculations to predict the results of a course of a semester of a student.

This sequence is such like that, first of all, f(0)=0,f(1)=1,f(n)=f(n2)+2f(n1)(n2) Then the definition of the QSC sequence is  g(n)=ni=0f(i)2 . If we know the birthday of the student is n, the year at the beginning of the semester is y, the course number x and the course total score s, then the forecast mark is  xg(ny)%(s+1) .
QSC sequence published caused a sensation, after a number of students to find out the results of the prediction is very accurate, the shortcoming is the complex calculation. As clever as you are, can you write a program to predict the mark?
 

Input
First line is an integer T(1≤T≤1000).

The next T lines were given n, y, x, s, respectively.

n、x is 8 bits decimal integer, for example, 00001234.

y is 4 bits decimal integer, for example, 1234.
n、x、y are not negetive.

1≤s≤100000000
 

Output
For each test case the output is only one integer number ans in a line.
 

Sample Input
  
  
2 20160830 2016 12345678 666 20101010 2014 03030303 333
 

Sample Output
  
  
1 317
题意:给出n,x,y,s
g(n)=f(0)*f(0)+f(1)*f(1)+...+f(n)*f(n)
f(n)=f(n-2)+2*f(n-1)
f(0)=0,f(1)=1
求x^(g(n*y))%(s+1)
题解:先算出次数,即g(n*y)
欧拉定理中 a^(φ(m))≡1(mod m)
所以 a^b%c=a^(b% φ(c)+φ(c))%c
f(n)*f(n)=4*f(n-1)*f(n-1)+f(n-2)*f(n-2)+4*f(n-2)f(n-1)
g(n)=g(n-1)+f(n-2)^2+4*f(n-2)^2+4*f(n-2)*f(n-1)
f(n-1)^2=f(n-2)^2
f(n)^2= f(n-2)^2+4*f(n-2)^2+4*f(n-2)*f(n-1)
f(n)*f(n-1)=(2*f(n-1)+f(n-2))*f(n-1)=2*f(n-1)^2+f(n-1)*f(n-2)
构造矩阵
| g(n-1) f(n-2)^2 f(n-1)^2 f(n-1)*f(n-2)| 
*
| 1 0 0 0 |
| 1 0 1 0 |
| 4 1 4 2 |
| 4 0 4 1 |
求解即可~
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
struct matrix{
	ll mas[5][5];
};
matrix per;
ll phi(ll n){
	ll ans=n,i;
	for(i=2;i*i<=n;i++){
		if(n%i==0){
			ans=ans-ans/i;
			while(n%i==0)n/=i;
		}
	}
	if(n>1)ans=ans-ans/n;
	return ans;
}
matrix multi(matrix a,matrix b,ll m){
	matrix ans;
	ll i,j,k;
	for(i=1;i<=4;i++){
		for(j=1;j<=4;j++){
			ans.mas[i][j]=0;
			for(k=1;k<=4;k++){
				ans.mas[i][j]=(ans.mas[i][j]+a.mas[i][k]*b.mas[k][j])%m;
			}
		}
	}
	return ans;
}
matrix quick(matrix a,ll k,ll m){
	matrix ans=per;
	while(k){
		if(k&1){
			ans=multi(ans,a,m);
		}
		k>>=1;
		a=multi(a,a,m);
	}
	return ans;
}
ll pow(ll a,ll k,ll m){
	ll ans=1;
	while(k){
		if(k&1){
			ans=ans*a%m;
		}
		a=a*a%m;
		k>>=1;
	}
	return ans;
}
int main(){
	ll n,y,x,s,t;
	scanf("%lld",&t);
	for(ll i=1;i<=4;i++){
		for(ll j=1;j<=4;j++){
			per.mas[i][j]=(i==j);
		}
	}
	while(t--){
		scanf("%lld%lld%lld%lld",&n,&y,&x,&s);
		ll mod=phi(s+1);
		ll ss;
		if(n*y<=3){
			if(n*y==1)ss=1;
			else if(n*y==2)ss=5;
			else if(n*y==3)ss=30;
			else ss=0;
		}
		else{
			matrix a;
			a.mas[1][1]=a.mas[2][1]=a.mas[2][3]=a.mas[3][2]=a.mas[4][4]=1;
			a.mas[3][1]=a.mas[4][1]=a.mas[3][3]=a.mas[4][3]=4;
			a.mas[1][2]=a.mas[2][2]=a.mas[4][2]=a.mas[1][3]=a.mas[1][4]=a.mas[2][4]=0;
			a.mas[3][4]=2;
			matrix as=quick(a,n*y-1,mod);
			ss=as.mas[1][1]+as.mas[3][1];
		}
		ll ans=pow(x,ss%mod+mod,s+1);
		cout<<ans<<endl;
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值