题目
思路
a
1
+
a
2
+
…
+
a
k
=
x
x
m
o
d
1000
a_1+a_2+…+a_k=x^x\bmod1000
a1+a2+…+ak=xxmod1000
啊先看这个式子的右边
x
x
m
o
d
1000
x^x\bmod 1000
xxmod1000,显然快速幂,完成这部分以后我们设右边为
n
n
n
再考虑左边:
我们把这个问题抽象成共
n
n
n个1,排成一排,我们要把他们分成
k
k
k个部分,问方案数。
我们考虑插板法,把
k
−
1
k-1
k−1个板子插到
n
−
1
n-1
n−1个空隙中,那么每一段的和就是
a
a
a数组。
那么方案数为
C
n
−
1
k
−
1
C^{k-1}_{n-1}
Cn−1k−1。
code:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
//When I wrote this code,God and I unterstood what was I doing
inline long long read()
{
long long ret,c,f=1;
while (((c=getchar())> '9'||c< '0')&&c!='-');
if (c=='-') f=-1,ret=0;
else ret=c-'0';
while ((c=getchar())>='0'&&c<='9') ret=ret*10+c-'0';
return ret*f;
}
long long ksm(long long x,long long y)
{
long long ans=1;
while (y)
{
if (y&1) ans=ans*x%1000;
x=x*x%1000;
y>>=1;
}
return ans;
}
long long k,x,c[1001];
void C(long long n,long long m)
{
memset(c,0,sizeof(c));
c[0]=c[1]=1;
for (long long i=1;i<=m;i++)
{
for (long long j=1;j<=c[0];j++)
{
c[j]*=(n-i+1);
}
for (long long j=1;j<=c[0];j++)
{
c[j+1]+=c[j]/10000;
c[j]%=10000;
}
while (c[c[0]+1]!=0) c[0]++;
long long q=0,wj=c[0];
while (wj>=1)
{
q=q*10000+c[wj];
c[wj]=q/i;
q=q%i;
wj--;
}
while (c[c[0]]==0) c[0]--;
}//压四位够了
return;
}
void print()
{
printf("%lld",c[c[0]]);
for (int i=c[0]-1;i>=1;i--)
{
printf("%lld%lld%lld%lld",c[i]/1000%10,c[i]/100%10,c[i]/10%10,c[i]%10);
}
return;
}
int main()
{
k=read(),x=read();
k--;
x=ksm(x,x)-1;
C(x,k);
print();
}
//Now,only God know