So Easy! HDU 4565


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









 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章