P2822 [NOIP2016 提高组] 组合数问题
0x01 题意
给定(n,m)和(k),对于所有的(0le ile n,0le jle min(i,m))有多少对((i,j))满足(k| binom{i}{j})。
(1)个(k),多组(n),(m)
0x02 解
预处理出来杨辉三角,因为第(i)行第(j)列就是( binom{i}{j})的值
(k)只有一个,所以可以把所有杨辉三角里的数(\%k)算(0)的个数就星了
但是会超时
用二维前缀和
注意算每行最后一个答案的时候,它上面的数就是,它左上方的数,因为( binom{n}{m}=0\,(n<m))
0x03 码
#include<bits/stdc++.h>
using namespace std;
const int N=2010;
int n,m,k,t;
int san[N][N],f[N][N];
int main(){
cin>>t>>k;
san[0][0]=san[1][0]=san[1][1]=1;
for(int i=2;i<=2000;i++){
san[i][0]=1;
for(int j=1;j<=i;j++){
san[i][j]=(san[i-1][j-1]%k+san[i-1][j]%k)%k;
f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1];
if(san[i][j]==0) f[i][j]++;
}
f[i][i+1]=f[i][i];
}
while(t--){
cin>>n>>m;
if(m>n) cout<<f[n][n]<<endl;
else cout<<f[n][m]<<endl;
}
return 0;
}