• Codeforces 582D. Number of Binominal Coefficients 题解


    题目链接:D. Number of Binominal Coefficients

    题目大意:洛谷


    题解:首先根据库默尔定理,可以得知(inom{a+b}{a})就是(p)进制下的(a+b)的进位次数,所以可以用数位 DP 解决,设置的状态是(f_{i,j,0/1,0/1})表示前(i)个数,进位(j)次,当前是否等于上届,当前是否有来自下一位的进位,然后非常非常麻烦的转移(花了我一个下午),然后就结束了。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    void read(int &a){
    	a=0;
    	char c=getchar();
    	while(c<'0'||c>'9'){
    		c=getchar();
    	}
    	while(c>='0'&&c<='9'){
    		a=(a<<1)+(a<<3)+(c^48);
    		c=getchar();
    	}
    }
    typedef long long ll;
    const int Maxn=10000;
    const int Mod=1000000007;
    int p,q,n,m,len;
    int a[Maxn+5];
    int b[Maxn+5];
    char s[Maxn+5];
    int f[2][Maxn+5][2][2];
    int div(int x){
    	ll num=0;
    	len=0;
    	for(int i=1;i<=m;i++){
    		num=num*10+a[i];
    		if(len>0||num>=x){
    			a[++len]=num/x;
    		}
    		num%=x;
    	}
    	for(int i=len+1;i<=m;i++){
    		a[i]=0;
    	}
    	m=len;
    	return num;
    }
    int main(){
    	read(p),read(q);
    	scanf("%s",s+1);
    	while(s[++m]!='');
    	m--;
    	for(int i=1;i<=m;i++){
    		a[i]=s[i]-'0';
    	}
    	while(m){
    		b[++n]=div(p);
    	}
    	for(int i=1;i<=n;i++){
    		a[i]=b[n-i+1];
    	}
    	if(n==0){
    		puts("0");
    		return 0;
    	}
    	f[0][0][1][0]=1;
    	for(int i=1;i<=n;i++){
    		int tmp_0=1ll*p*(p+1)/2%Mod,tmp_1=1ll*p*(p-1)/2%Mod,tmp_2=1ll*a[i]*(a[i]+1)/2%Mod,tmp_3=1ll*a[i]*(a[i]-1)/2%Mod,tmp_4=1ll*a[i]*(p+p-a[i]-1)/2%Mod,tmp_5=1ll*a[i]*(p+p-a[i]+1)/2%Mod;
    		memset(f[1],0,sizeof f[1]);
    		for(int j=0;j<i;j++){
    			f[1][j][0][0]=(f[1][j][0][0]+1ll*f[0][j][0][0]*tmp_0+1ll*f[0][j][1][0]*tmp_2)%Mod;
    			f[1][j][0][1]=(f[1][j][0][1]+1ll*f[0][j][0][0]*tmp_1+1ll*f[0][j][1][0]*tmp_3)%Mod;
    			f[1][j][1][0]=(f[1][j][1][0]+1ll*f[0][j][1][0]*(a[i]+1))%Mod;
    			f[1][j][1][1]=(f[1][j][1][1]+1ll*f[0][j][1][0]*a[i])%Mod;
    			f[1][j+1][0][0]=(f[1][j+1][0][0]+1ll*f[0][j][0][1]*tmp_1+1ll*f[0][j][1][1]*tmp_4)%Mod;
    			f[1][j+1][0][1]=(f[1][j+1][0][1]+1ll*f[0][j][0][1]*tmp_0+1ll*f[0][j][1][1]*tmp_5)%Mod;
    			f[1][j+1][1][0]=(f[1][j+1][1][0]+1ll*f[0][j][1][1]*(p-a[i]-1))%Mod;
    			f[1][j+1][1][1]=(f[1][j+1][1][1]+1ll*f[0][j][1][1]*(p-a[i]))%Mod;
    		}
    		swap(f[0],f[1]);
    	}
    	int ans=0;
    	for(int i=q;i<=n;i++){
    		ans=(ans+f[0][i][0][0])%Mod;
    		ans=(ans+f[0][i][1][0])%Mod;
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    json格式转换
    早该知道的7个JavaScript技巧
    SPFA加上SLF时判负环的条件
    HDU 4061 A Card Game
    线性筛法求素数
    STL之deque
    POJ 3219 二项式系数
    HDU 4296 Buildings
    HDU 4292 Food (成都赛区网络赛第五题,拆点网络流)
    拆点网络流(POJ3281)
  • 原文地址:https://www.cnblogs.com/withhope/p/13602723.html
Copyright © 2020-2023  润新知