求
我们设 f(n,k)表示∑ni=1i−1对pk取模的结果
我们假设n对p取模为0,不是的话把多余部分暴力然后把n变为模p为0。
然后n以内的可以分成两类:是p的倍数和不是p的倍数。
设第一类的结果为S,那么
#include<cstdio>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
ll i,j,k,l,t,n,m,a,b,p;
ll su[150][150];
ll f[150];
ll qsm(ll x,ll y){
if (!y) return 1;
ll t=qsm(x,y/2); t=t*t%m; if (y%2) t=t*((x%m+m)%m)%m; return t; } ll get(ll n,ll k){ su[0][0]=1; ll i,j; fo(i,1,k) su[i][0]=0,su[i][i]=1; fo(i,1,k) fo(j,1,i-1) su[i][j]=(su[i-1][j-1]+(i-1)*su[i-1][j]%m)%m; if (!n) return 0; if (n<=k){ t=0; fo(i,1,n){ l=1; fo(j,1,k) l=l*i%m; t=(t+l)%m; } return t; } fo(i,0,k) f[i]=0; if (n%2==0) f[1]=n/2*(n+1)%m; else f[1]=n*(n+1)/2%m;
f[0]=n%m;
f[1]=(f[1]+1)%m;
fo(i,2,k){
t=1;
fo(j,n+1-i,n+1)
if (j%(i+1)==0) t=t*j/(i+1)%m;else t=t*j%m;
f[i]=t;
fo(j,0,i-1){
if ((j+i)%2==0) l=1;else l=-1;
f[i]=((f[i]-l*su[i][j]%m*f[j]%m)%m+m)%m;
}
f[i]=f[i]%m;
}
return ((f[k]-1)%m+m)%m;
}
void gcd(ll a,ll b,ll &x,ll &y){
if (!b){
x=1;
y=0;
return;
}
else{
gcd(b,a%b,x,y);
swap(x,y);
y-=x*(a/b);
}
}
ll getny(ll a,ll b){
ll x,y;
gcd(a,b,x,y);
x=(x%b+b)%b;
return x;
}
ll solve(ll n,ll k){
if (!n) return 0;
ll ans=0,t,mo,r,i;
r=n-(n/p)*p;
n-=r;
fo(a,1,p-1){
t=getny(a,m);
fo(b,0,k)
ans=(ans+t*qsm(-t*p,b)%m*get(n/p-1,b)%m)%m;
}
fo(i,n+1,n+r)
if (i%p!=0) ans=(ans+getny(i,m))%m;
n+=r;
mo=m;
m=m*p;
ans=(ans+solve(n/p,k+1)/p)%mo;
ans=(ans%mo+mo)%mo;
return ans;
}
int main(){
scanf("%lld%lld%lld",&p,&k,&n);
m=1;
fo(i,1,k) m=m*p;
printf("%lld\n",solve(n,k));
}