So Easy!
先吐槽一下吧
完全没有想要做这个题,本来我在学 FFT 专题的,然后有个题不会搜题解,好不容易找到了一个,真坑
然后看着一脸懵,完全不知道讲的啥,在一个小时之后我选择了放弃,准备敲一个矩阵快速幂,A了就跑,反正有递推公式不用自己推,然而等我敲完发现这TM 完全是两个题好吧,没事能不能不要瞎贴题解。题目还一样......
本来在做 :点击打开链接
——————————————————————————————————————————————————————————
题意很简单,然而题目并不简单,也可能很简单吧(ORZ)
思路: 考虑 {(a+ sqrt(b) )^n }
分析有 { ( a+sqrt(b) )^n } =( a+sqrt(b) )^n+( a-sqrt(b) )^n;
然后根据上面的式子求出 递推式 Cn+1=2*a*Cn-(a^2-b)*Cn-1;
(求递推式这个需要好好研究一下)
套矩阵快速幂的模板就行了;
具体分析: 点击打开链接
#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include <bits/stdc++.h>
#include<string>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#define maxn 100100
#define INF 0x3f3f3f3f
#define MOD 1000003
#define ll long long
using namespace std;
struct Node
{
ll a[3][3];
Node()
{
memset(a,0,sizeof a);
}
};
int m;
Node Mul(Node A,Node B)
{
Node C;
for(int i=1;i<=2;i++)
{
for(int j=1;j<=2;j++)
{
C.a[i][j]=0;
for(int k=1;k<=2;k++)
{
C.a[i][j]+=A.a[i][k]*B.a[k][j];
}
C.a[i][j]%=m;
if(C.a[i][j]<0)C.a[i][j]+=m;
}
}
return C;
}
Node Pow(Node A,int p)
{
Node B;
B.a[1][1]=B.a[2][2]=1;
while(p)
{
if(p&1)B=Mul(B,A);
A=Mul(A,A);
p>>=1;
}
return B;
}
int main()
{
int a,b,n;
while(scanf("%d%d%d%d",&a,&b,&n,&m)!=EOF)
{
Node A;
A.a[1][1]=2;
A.a[2][1]=2*a;
Node B;
B.a[1][1]=0;
B.a[2][1]=b-a*a;
B.a[1][2]=1;
B.a[2][2]=2*a;
B=Pow(B,n);
A=Mul(B,A);
cout<<A.a[1][1]<<endl;
}
return 0;
}