当前位置: 代码迷 >> 综合 >> 51nod 1245 Binomial Coefficients Revenge
  详细解决方案

51nod 1245 Binomial Coefficients Revenge

热度:1   发布时间:2024-01-19 01:52:15.0

C(M,N) = M! / N! / (M - N)! (组合数)。给出M和质数p,求C(M,0), C(M,1)......C(M,M)这M + 1个数中,有多少数不是p的倍数,有多少是p的倍数但不是p^2的倍数,有多少是p^2的倍数但不是p^3的倍数......。
例如:M = 10, P = 2。C(10,0) -> C(10,10)
分别为:1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1。
P的幂 = 1 2 4 8 16......

1 45 45 1 这4个数只能整除1。
10 210 210 10这4个数能整除2但不能整除4。
252 能整除4但不能整除8。
120 120 这2个数能整除8但不能整除16。

所以输出:4 4 1 2。
Input
第1行:一个数T,表示输入的测试数量(1 <= T <= 5000)
第2 - T + 1行:每行2个数,M和P,中间用空格分隔(2 <= M, P <= 10^18)
Output
输出共T行,每行若干个数,中间用空格分隔,对应组合数的数量。
Input示例
3
4 5
6 3
10 2
Output示例
5
3 4
4 4 1 2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

数位DP+思路~

神奇的题解链接:http://blog.csdn.net/qq_20669971/article/details/53780505~

(逃


#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define ll long longll t,n,p,a[65],tot,f[2][65][65],now;
bool kkz;ll read()
{ll x=0,f=1;char ch=getchar();while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}while(ch>='0' && ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;
}int main()
{t=read();while(t--){n=read();p=read();tot=0;while(n) a[tot++]=n%p,n/=p;tot--;memset(f[kkz],0,sizeof(f[kkz]));f[kkz][0][0]=a[0]+1;f[kkz][1][1]=p-f[kkz][0][0];for(int i=1;i<=tot;i++){kkz^=1;memset(f[kkz],0,sizeof(f[kkz]));for(int j=0;j<=tot;j++){f[kkz][j][0]+=(a[i]+1)*f[kkz^1][j][0]+a[i]*f[kkz^1][j][1]; f[kkz][j+1][1]+=(p-a[i]-1)*f[kkz^1][j][0]+(p-a[i])*f[kkz^1][j][1];}}now=tot;while(!f[kkz][now][0]) now--;for(int i=0;i<=now;i++) printf("%lld ",f[kkz][i][0]);printf("\n");}return 0;
}