[NOIp2016提高组]组合数问题
题目大意:
给定n,m和k,对于所有的0<=i<=n,0<=j<=min(i,m)有多少对(i,j)满足C(j,i)是k的倍数。
思路:
先预处理出组合数,再预处理一下能整除个数的前缀和,最后直接答即可。
1 #include<cstdio> 2 #include<cctype> 3 inline int getint() { 4 register char ch; 5 while(!isdigit(ch=getchar())); 6 register int x=ch^'0'; 7 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 8 return x; 9 } 10 const int N=2001; 11 int c[N][N],s[N][N]; 12 int main() { 13 int T=getint(),k=getint(); 14 for(register int i=0;i<N;i++) { 15 c[i][0]=1; 16 for(register int j=1;j<=i;j++) { 17 c[i][j]=(c[i-1][j-1]+c[i-1][j])%k; 18 } 19 } 20 for(register int i=1;i<N;i++) { 21 for(register int j=1;j<N;j++) { 22 s[i][j]=s[i][j-1]+s[i-1][j]-s[i-1][j-1]; 23 if(!c[i][j]&&j<=i) s[i][j]++; 24 } 25 } 26 while(T--) { 27 const int n=getint(),m=getint(); 28 printf("%d\n",s[n][m]); 29 } 30 return 0; 31 }