1. 程式人生 > >BZOJ 3328: PYXFIB 二項式定理 原根 構造

BZOJ 3328: PYXFIB 二項式定理 原根 構造

題目大意:自己看去
題解:這真是一道神題,由於有大量的數學公式,不太好寫(我懶,就附個連結吧

題解戳我

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<string>
#include<algorithm>
#include<ctime>
#include<cmath>
using namespace std;
#define int long long
#define mod p int ys[100000]; int top=0; void fenjie(int n) { top=0; int i; for(i=2;i*i<n;i++) if(n%i==0) ys[++top]=i,ys[++top]=n/i; if(i*i==n) ys[++top]=i; } long long n,k,p; long long ksm(long long x,long long t) { long long re=1; while(t) { if(t&1
) re=re*x%mod; x=x*x%mod; t>>=1; } return re; } bool jud(int x) { for(int i=1;i<=top;i++) if(ksm(x,ys[i])==1) return false; return true; } int get_w() { fenjie(p-1); for(int i=2;;i++) if(jud(i)) return ksm(i,(p-1)/k); } struct zz { long
long a[3][3]; zz operator + (zz b) const { zz mid; for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) mid.a[i][j]=(a[i][j]+b.a[i][j])%p; return mid; } zz operator * (long long b) const { zz mid; for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) mid.a[i][j]=a[i][j]*b%p; return mid; } zz operator * (zz b) const { zz mid; for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) { mid.a[i][j]=0; for(int k=1;k<=2;k++) { mid.a[i][j]+=a[i][k]*b.a[k][j]; mid.a[i][j]%=p; } } return mid; } }trans,ji; long long ksm(zz x,long long t) { zz re=ji; while(t) { if(t&1) re=re*x; t>>=1; x=x*x; } return (re.a[1][1]+re.a[2][1])%mod; } void init() { ji.a[1][1]=ji.a[2][2]=1; trans.a[1][1]=0; trans.a[1][2]=trans.a[2][1]=trans.a[2][2]=1; } int w; void print(zz b) { for(int i=1;i<=2;i++,cout<<endl) for(int j=1;j<=2;j++,cout<<" ") cout<<b.a[i][j]; } main() { int T; scanf("%lld",&T); init(); while(T--) { scanf("%lld%lld%lld",&n,&k,&p); w=get_w(); long long trueans=0; for(int j=0;j<k;j++) { long long x=ksm(ksm(w,j),p-2); trueans+=ksm(ksm(x,n),p-2)*(ksm(trans+(ji*x),n)); trueans%=p; } trueans*=ksm(k,p-2); trueans%=p; printf("%lld\n",trueans); } return 0; }