PYXFIB

思路:

$\sum\limits_{i=0}^{\lfloor \frac{n}{k} \rfloor} C_{n}^{i*k} * F_{i*k}$

 

$=\sum\limits_{i=0}^{n} C_{n}^{i}*F_{i}*[k|i]$

然后应该思考$[k|i]$的性质

在看看题目,发现了一个奇奇怪怪的条件:$(k|(p-1))$

这个还是比较容易联系到原根的

那我们试图用一个包含$原根,i,k$的式子表示出$[k|i]$

大胆尝试:$[k|i]=\sum\limits_{j=0}^{k-1} \omega^{ij}/k$

当$[k|i]=0$时,我们希望找到一个最高项为$\omega^{r*k-1}$的等比序列,这样可以使$\frac{1-\omega^{r*k}}{1-d}=0$

当$[k|i]=1$时,可以利用原根的性质使得每1项都为1

然后我们就可以继续往下推式子了

$Ans=\sum\limits_{i=0}^{n} C_{n}^{i}*F_{i}*[k|i]$

$=\frac{1}{k}\sum\limits_{i=0}^{n} C_{n}^{i}*F_{i}*\sum\limits_{j=0}^{k-1} \omega^{ij}$

$=\frac{1}{k}\sum\limits_{i=0}^{n} C_{n}^{i}*A^{i}[0][0]*\sum\limits_{j=0}^{k-1} \omega^{ij} \space \space 然后配方$

$=\frac{1}{k}\sum\limits_{j=0}^{k-1} \omega^{ij} * \sum\limits_{i=0}^{n} C_{n}^{i}*A^{i}[0][0]$

$=\frac{1}{k}\sum\limits_{j=0}^{k-1} \sum\limits_{i=0}^{n} C_{n}^{i}*A^{i}[0][0]*\omega^{(-i)*(-j)}$

设$x=\omega^{-j}$

$则Ans=\frac{1}{k}\sum\limits_{j=0}^{k-1} \sum\limits_{i=0}^{n} C_{n}^{i}*A^{i}[0][0]*x^{-i}$

$=\frac{1}{k}\sum\limits_{j=0}^{k-1} x^{-n}*\sum\limits_{i=0}^{n} C_{n}^{i}*A^{i}[0][0]*x^{n-i}$

$=\frac{1}{k}\sum\limits_{j=0}^{k-1} x^{-n}*(xI+A)^n$ 

#include<bits/stdc++.h>
#define maxn 100005
#define maxm 500005
#define inf 0x7fffffff
#define ll long long
#define rint register int
#define debug(x) cerr<<#x<<": "<<x<<endl
#define fgx cerr<<"--------------"<<endl
#define rep(i,a,b) for(ll i=a;i<=b;i++)
#define dgx cerr<<"=============="<<endl
#define lowbit(x) (x&(-x))
#define N 1000000
#define MAXN 1000004
using namespace std;
inline ll read(){
	ll x=0,f=1;
	char ch=getchar();
	while('0'>ch || ch>'9'){if(ch=='-') f=-1; ch=getchar();}
	while('0'<=ch && ch<='9'){x=(x<<1)+(x<<3)+ch-'0'; ch=getchar();}
	return x*f;
}
ll mod,n,k,Wn,w,book[MAXN],pre[MAXN],cnt,phi[MAXN];

struct mac{
	ll a[2][2];
	mac(){a[0][0]=a[1][0]=a[0][1]=a[1][1]=0;}
}A;
mac pls(mac c,mac d){
	rep(i,0,1) rep(j,0,1) c.a[i][j]=(c.a[i][j]+d.a[i][j])%mod;
	return c;
} 
void print(mac gg){
	cout<<"MAC:"<<endl;
	rep(i,0,1){
		rep(j,0,1) cout<<gg.a[i][j]<<" ";cout<<endl;
	}
}
ll ksm(ll x,ll y){
	ll res=1;
	while(y){
		if(y&1) res=(res*x)%mod;
		x=(x*x)%mod;
		y>>=1;
	}
	return res;
}
mac mul(mac x,mac y){
	mac f;
	rep(i,0,1){
		rep(j,0,1){
			rep(k,0,1){
				f.a[i][j]+=x.a[i][k]*y.a[k][j]; f.a[i][j]%=mod;
			}
		}
	}
	return f;
} 
int get_root(int x) {
	if(x<=2) return 1;
	rep(i,2,x){
		if(ksm(i,(x-1))!=1) continue;
		bool zlk=0;
		for(int j=2;j*j<=x-1;j++) if((x-1)%j==0 && (ksm(i,j)==1 || ksm(i,(x-1)/j)==1)){zlk=1; continue;}
	    if(!zlk) return i;
	}
}
void init(ll x){
	A.a[0][0]=1+x; A.a[0][1]=1;
	A.a[1][0]=1; A.a[1][1]=x;
}
mac mac_ksm(mac base,ll y){
	mac res; res.a[0][0]=res.a[1][1]=1;
	while(y){
		if(y&1) res=mul(res,base);
		base=mul(base,base);
		y>>=1;
	}
	return res;
}
ll ans=0,sum=0;

int main(){
	int t=read(); 
    while(t--){
    	n=read(); k=read(); mod=read();
    	ll g=get_root(mod),gg;
    	w=1; sum=0;
    	ll omg=ksm(g,(mod-1)/k);
    	rep(i,0,k-1){
    		gg=ksm(omg,k-i);
    		init(gg);
    		mac pp=mac_ksm(A,n);
    		sum=(sum+pp.a[0][0]*ksm(omg,i*(n%k)))%mod;
		}
		ans=sum*ksm(k,mod-2)%mod;
		printf("%lld\n",ans);
	}
	return 0;
}

 

posted @ 2021-03-08 16:12  niolle  阅读(78)  评论(0编辑  收藏  举报