0
点赞
收藏
分享

微信扫一扫

So Easy! HDU - 4565


​​So Easy! HDU - 4565​​

思路:题意虽然写着so easy 但是emmmm没想到怎么处理这个小数情况。看了题解:

So Easy! HDU - 4565_#include

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
ll mod;
struct matrix{
ll x[2][2];
};
matrix multi(matrix a,matrix b){
matrix temp;
memset(temp.x,0,sizeof(temp.x));
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
{
temp.x[i][j]+=a.x[i][k]*b.x[k][j];
temp.x[i][j]%=mod;
if(temp.x[i][j]<0) temp.x[i][j]=(temp.x[i][j]+mod)%mod;//负数情况
}
return temp;
}
matrix quick_multi(matrix a,ll n)//矩阵快速幂
{
matrix temp=a;
n--;
while(n){
if(n&1)
temp=multi(temp,a);
a=multi(a,a);
n>>=1;
}
return temp;
}
/*void p(matrix a)
{
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
printf("%lld,a.x[i][j]);
printf("\n");
}
}*/
int main()
{
ll a,b,n;
while(scanf("%lld%lld%lld%lld",&a,&b,&n,&mod)!=EOF)
{
matrix A;
A.x[0][0]=(2*a)%mod;A.x[0][1]=(-(a*a)%mod+b)%mod;A.x[1][0]=1;A.x[1][1]=0;
ll tmp=sqrt(b);
if(tmp*tmp<b) tmp+=1;
ll tmp2=2*a*sqrt(b);
if(tmp2<2*a*tmp) tmp2+=1;
tmp2=(a*a+b+tmp2)%mod;
if(n<=2) n==1?printf("%lld\n",(a+tmp)%mod):printf("%lld\n",tmp2);
else
{
matrix B;
memset(B.x,0,sizeof(B.x));
B.x[0][0]=(tmp2)%mod;B.x[1][0]=(a+tmp)%mod;
A=quick_multi(A,n-2);
B=multi(A,B);
printf("%lld\n",(B.x[0][0]+mod)%mod);//负数情况
}
}
return 0;
}


举报

相关推荐

0 条评论