题解 P5160 【WD与循环】
题意:询问有多少个由非负整数构成的序列
满足
如果是
那么如果是
我看看数据范围就放弃了暴力。但是我打了一个杨辉三角的表就发现:
也就是
所以和lucas定理模板题就是双倍经验了
这是为什么呢?
我们考虑数学归纳法。
证明:
若 什么鬼证明
假设
根据组合数的性质(杨辉三角的性质)
即对于
综上所述,对于
这题就变成一道组合数裸题了。
题目出的还是挺不错的。套一下 Lucas 就好了!
个人感觉是蓝~紫题吧,评成黑题的话就有点厉害了。
代码:
#include<bits/stdc++.h>
#define LL long long
using namespace std;
LL fa[19491003],T,n,m,pp;
LL fast_pow(LL a,LL b,LL p){
LL t=1;a%=p;
while (b>0){
if (b%2) t=t*a%p;
b/=2;a=(a*a)%p;
}
return t;
}
LL un(LL a,LL p){
return fast_pow(a,p-2,p);
}
void _init(LL p){
fa[0]=1;
for (int i=1;i<=p;i++){
fa[i]=fa[i-1]*(i%p);fa[i]%=p;
}
}
LL C(LL n,LL m,LL p){
if (n<m) return 0;
return fa[n]*un(fa[n-m],p)%p*un(fa[m],p)%p;
}
LL fast_C(LL n,LL m,LL p){
if (n<m) return 0;
if (!n) return 1;
return fast_C(n/p,m/p,p)%p*C(n%p,m%p,p)%p;
}
int main(){
scanf("%lld",&T);
_init(19491001);
while (T--){
scanf("%lld%lld",&n,&m);
printf("%lld\n",fast_C(n+m,m,19491001));
}
}