传送门
【题目分析】
不得不说NOIP DAY2还是有点东西啊。。。。。。
考虑组合数的计算:,又有,那么就根据这个打印出前5行组合数:
眼熟的感觉。。。。没错这就是杨辉三角。。。。。
所以在预处理2000*2000的杨辉三角的时候记录一下当前列有多少为k的倍数,然后直接O(1)询问即可。
PS:注意m可能大于n所以输出时取个较小值即可
【代码~】
#include<bits/stdc++.h>
using namespace std;
const int MAXN=2e3+10;
int T,k;
int n,m;
int c[MAXN][MAXN],ans[MAXN][MAXN],cnt[MAXN];
int Read(){
int i=0,f=1;
char c;
for(c=getchar();(c>'9'||c<'0')&&c!='-';c=getchar());
if(c=='-')
f=-1,c=getchar();
for(;c>='0'&&c<='9';c=getchar())
i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
void pre(){
for(int i=0;i<=2000;++i)
c[i][0]=1;
for(int i=1;i<=2000;++i){
for(int j=1;j<=i;++j){
c[i][j]=(c[i-1][j-1]+c[i-1][j])%k;
if(!c[i][j])
cnt[j]++;
ans[i][j]=ans[i][j-1]+cnt[j];
}
}
}
int main(){
T=Read(),k=Read();
pre();
while(T--){
n=Read(),m=Read();
cout<<ans[n][min(m,n)]<<'\n';
}
return 0;
}