您的位置:首页 > 其它

【Ural】【1057】Amount of degrees

2015-03-01 11:15 260 查看

数位DP

2009年刘聪《浅谈数位类统计问题》 例题一

从组合数 以及 数位DP的角度都可以做……

首先转化成求1~n内K进制下只有0、1的数的个数:

  考虑K进制下第一个为1的位,剩下的数位中0和1随便放……也就是算组合数了。

  然后区间相减……

写的好乱……还是去看论文吧

//Ural 1057
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
using namespace std;

int getint(){
int v=0,r=1; char ch=getchar();
for(;ch<'0' || ch>'9';ch=getchar()) if (ch=='-') r=-1;
for(;ch>='0'&&ch<='9';ch=getchar()) v=v*10+ch-'0';
return v*r;
}
/*******************template********************/
int f[40][40];
void init(){
f[0][0]=1;
F(i,1,31){
f[i][0]=f[i-1][0];
F(j,1,i) f[i][j]=f[i-1][j]+f[i-1][j-1];
}
}
int calc(int x,int k){
int tot=0,ans=0;
D(i,31,1){
if (x&(1<<i)){
++tot;
if(tot>k)break;
x=x^(1<<i);
}
if ( (1<<(i-1))<=x )
ans+=f[i-1][k-tot];
}
if (tot+x==k) ++ans;
return ans;
}
int a[40];
int change(int x,int b){
int l=0;
for(l=0;x;l++,x/=b) a[l]=x%b;
D(i,l-1,0) if (a[i]>1){
D(j,i,0) a[j]=1;
break;
}
int temp=0;
D(i,l-1,0) temp=(temp<<1)+a[i];
return temp;
}
int main(){
//    freopen("input.txt","r",stdin);
init();
int l=getint(),r=getint(),k=getint(),b=getint();
int ans=0;
if (b!=2) ans=calc(change(r,b),k)-calc(change(l-1,b),k);
else ans=calc(r,k)-calc(l-1,k);
printf("%d\n",ans);
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: