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;
}