1. 程式人生 > >Ural 1057 Amount of Degrees【數位DP】

Ural 1057 Amount of Degrees【數位DP】

轉成二進位制,組合數搞一下:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define repl(i,x,y) for(ll i=(x);i<(y);i++)
#define repd(i,x,y) for(ll i=(x);i>=(y);i--)
using namespace std;

const ll N=1e3+5;

ll x,y,k,b,w[N];

ll c[N][N];

void split(ll num) {
	w[0]=0;
	while(num) {
		w[++w[0]]=num%b;num/=b;
	}
}

ll getans(ll s) {
	split(s);
	
	ll cnt=0,sum=0;
	
	repd(i,w[0],1) {
		if(w[i]==1) {
			sum+=c[i-1][k-cnt];
			if(++cnt==k) break;
		} else if(w[i]>1) {
			sum+=c[i][k-cnt];break;	
		}
	}	
	
	if(cnt==k) sum++;	
	
	return sum;
}

int main() {
	rep(i,0,35) c[i][0]=1;

	rep(i,1,35) rep(j,1,i) c[i][j]=c[i-1][j-1]+c[i-1][j];
	
	while(~scanf("%lld%lld%lld%lld",&x,&y,&k,&b)) {
		printf("%lld\n",getans(y)-getans(x-1));
	}
	
	return 0;
}