洛谷日报。。。
∑
i
=
0
n
−
1
ω
n
k
i
n
=
[
n
∣
k
]
\frac{\sum_{i=0}^{n-1}\omega^{ki}_n}n=[n|k]
n∑i=0n−1ωnki=[n∣k]
对于原根显然适用。
无聊打了一发BZOJ 3328: PYXFIB
居然1A,这让我怎么在NOI(退役)前攒RP啊
AC Code:
#include<bits/stdc++.h>
#define maxn 20005
#define LL long long
using namespace std;
int k,p;
LL n;
struct mat{
int a[2][2];
mat(int d=0){ a[0][0] = a[1][1] = d, a[0][1] = a[1][0] = 0; }
mat operator *(const mat &B)const{
mat ret;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++) if(a[i][j])
for(int k=0;k<2;k++) if(B.a[j][k])
ret.a[i][k] = (ret.a[i][k] + 1ll * a[i][j] * B.a[j][k]) % p;
return ret;
}
mat operator *(const int &B)const{
mat ret;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
ret.a[i][j] = a[i][j] * 1ll * B % p;
return ret;
}
}A;
int Pow(int base,int k){
int ret = 1;
for(;k;k>>=1,base=1ll*base*base%p)
if(k&1)
ret=1ll*ret*base%p;
return ret;
}
mat Pow(mat base,LL k){
mat ret = mat(1);
for(;k;k>>=1,base=base*base)
if(k&1)
ret=ret*base;
return ret;
}
int main(){
int T;
A.a[0][0] = A.a[1][0] = A.a[0][1] = 1;
for(scanf("%d",&T);T--;){
scanf("%lld%d%d",&n,&k,&p);
int G=0;
vector<int>pi;
int tmp = p-1;
for(int i=2;i*i<=tmp;i++)
if(tmp % i == 0){
while(tmp % i == 0) tmp/=i;
pi.push_back(i);
}
if(tmp > 1) pi.push_back(tmp);
for(int i=2;i<p;i++){
bool flg = 0;
for(int j=0;j<pi.size();j++){
int u = pi[j];
if(Pow(i,(p-1)/u) == 1){
flg = 1;
break;
}
}
if(!flg){
G = i;
break;
}
}
int ans = 0;
for(int i=0,pw=Pow(G,(p-1)/(k)),w=1;i<k;i++,w=1ll*w*pw%p){
mat B = A * w;
B.a[0][0] ++ , B.a[1][1]++;
B = Pow(B,n);
ans = (ans + B.a[0][0]) % p;
}
ans = 1ll * ans * Pow(k,p-2) % p;
printf("%d\n",(ans+p)%p);
}
}