zoukankan      html  css  js  c++  java
  • Ural 1057 Amount of Degrees

    Description

    问[L,R]中有多少能表示k个b次幂之和.

    Sol

    数位DP.

    当2进制时.

    建出一个二叉树, (f[i][j]) 表示长度为 (i) 有 (j) 个1的个数.

    递推式就是左右子树之和 (f[i][j]=f[i-1][j-1]+f[i-1][j])

    将b进制变成2进制来做.

    因为发现系数只能是1,所以找到一个b进制下极大的2进制就行..我觉得我好像讲不明白..

    我计算的是小于 x 满足条件的...我觉得这样比较好写,也不用特判最后的情况..

    复杂度 (O(log^2 n))

    Code

    #include <cstdio>
    #include <iostream>
    using namespace std;
    
    #define debug(a) cout<<#a<<"="<<a<<" "
    const int N = 64;
    typedef long long LL;
    
    LL l,r,k,b;
    LL f[N][N];
    
    void init() {
    	f[0][0]=1;
    	for(int i=1;i<32;i++) {
    		f[i][0]=1;
    		for(int j=1;j<=i;j++) f[i][j]=f[i-1][j]+f[i-1][j-1];
    	}
    //	for(int i=0;i<6;i++) {
    //		for(int j=0;j<=i;j++) cout<<f[i][j]<<" ";cout<<endl;
    //	}
    }
    LL calc(LL x) {
    	LL t=1,r=0,c=0;
    	for(;t<x;t*=b,c++);
    	for(;x;t/=b,c--) if(x>=t) {
    		if(x>=2*t) {
    			return r+(1<<(c+1))-1;
    		}else {
    			x%=t,r+=1<<c;
    		}
    	}
    	return r;
    }
    int DP(LL x) {
    	int r=0,c=k;
    	for(int i=31;~i;i--) {
    		if(x & (1LL<<i)) {
    			if(c>=0) r+=f[i][c];
    			c--;
    //			debug(i),debug(f[i][c])<<endl;
    		}
    	}return r;
    }
    int main() {
    //	freopen("in.in","r",stdin);
    	init();
    	
    	cin>>l>>r>>k>>b;
    	
    //	debug(calc(r)),debug(calc(l-1))<<endl;
    //	debug(DP(calc(r))),debug(DP(calc(l-1)))<<endl;
    	
    	cout<<DP(calc(r+1))-DP(calc(l))<<endl;
    	return 0;
    }
    

      

  • 相关阅读:
    video 安卓ios系统 浏览器 全屏播放以及自动播放的问题
    echarts 雷达图的个性化设置
    AtCoder Grand Contest 015 题解
    AtCoder Grand Contest 014 题解
    bzoj 3242: [Noi2013]快餐店
    bzoj 2794: Cloakroom dp
    bzoj 4261: 建设游乐场 费用流
    uoj problem 31 猪猪侠再战括号序列
    APIO2017 游记
    CTSC2017 游记
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6183485.html
Copyright © 2011-2022 走看看