LOJ P10163 Amount of Degrees 题解

每日一题 day6 打卡

Analysis

题目的意思是找在区间[x,y]之间满足能够由k个b的不同次幂相加得到的数的总数。这题的关键是转换进制,之前几道题我们保存的是数的每位数,其实也就是10进制,这题我们要保存的是b进制,所以在ask函数中要把原来的对10求余和除10都要改成对b进行操作,dp[x][pre]数组表示第x位由pre个b的不同次幂相加得到的数的总数。在判断进入递归的if条件语句中,i的上界要同时满足小于上界且小于等于1,因为根据题意,只有类似3^4次方能够算进去,2*3^4并不能计入,也就是说系数必须小于等于0,且只有等于1时,sta才能增1。还有最后一个要注意的是当x=0递归结束时,只有当pre=k时,才是符合条件的数,ans才能增加。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define fa_q 5010
 7 using namespace std;
 8 typedef long long ll;
 9 inline ll read() 
10 {
11     ll x=0;
12     bool f=1;
13     char c=getchar();
14     for(; !isdigit(c); c=getchar()) if(c=='-') f=0;
15     for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0';
16     if(f) return x;
17     return 0-x;
18 }
19 inline void write(ll x)
20 {
21     if(x<0){putchar('-');x=-x;}
22     if(x>9)write(x/10);
23     putchar(x%10+'0');
24 }
25 ll dp[fa_q][fa_q],dim[fa_q];
26 ll x,y,k,b;
27 ll dfs(int x,int pre,int bj)
28 {
29     if(x==0) return pre==k;
30     if(!bj&&dp[x][pre]!=-1) return dp[x][pre];
31     int maxn=bj?dim[x]:b-1;
32     ll temp=0;
33     for(int i=0;i<=min(maxn,1);i++)
34     {
35         temp+=dfs(x-1,pre+(i==1),bj&&i==maxn);
36     }
37     if(!bj) dp[x][pre]=temp;
38     return temp;
39 }
40 ll ask(ll x)
41 {
42     dim[0]=0;
43     while(x)
44     {
45         dim[++dim[0]]=x%b;
46         x/=b;
47     }
48     return dfs(dim[0],0,1);
49 }
50 int main()
51 {
52     memset(dp,-1,sizeof(dp));
53     x=read();y=read();k=read();b=read();
54     write(ask(y)-ask(x-1));
55     return 0;
56 }

请各位大佬斧正(反正我不认识斧正是什么意思)

转载于:https://www.cnblogs.com/handsome-zyc/p/11460659.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值