Salazar Slytherin's Locket CodeForces - 855E

Salazar Slytherin's Locket CodeForces - 855E

http://www.cnblogs.com/ftae/p/7590187.html

数位dp:

http://www.cnblogs.com/xz816111/p/4809913.html

http://blog.csdn.net/wust_zzwh/article/details/52100392

1.

 1 #include<cstdio>
 2 #include<cstring>
 3 typedef long long LL;
 4 LL q,b,l,r;
 5 LL ans[11][70][2049][2];
 6 LL w[70];//记录拆出来的i进制的各个数字
 7 //ans[i][j][state][k]:i进制,i进制下j长度,状态为state,k表示是否处于前导0
 8 //状态为0-b-1的数字出现奇数/偶数次
 9 LL dp(LL jz,LL pos,LL state,bool pre0,bool limit)//pre0表示当前位的前一位是不是0
10 {
11     if(pos<1)    return !state;//只有状态全0也就是所有数字出现偶数次才有1个答案,曾经忘记
12     if(!limit&&ans[jz][pos][state][pre0]!=-1)
13         return ans[jz][pos][state][pre0];
14     LL i,res=0,end=limit?w[pos]:(jz-1);//当前位上界,limit为0表示前面某一位已经取了不是最高值,那么后面的位可以取0-9//曾经把最大值错写成9
15     for(i=0;i<=end;i++)
16         if(i==0&&pre0)//如果当前位取0,且前面都是前导0,那么开头的0显然是不计入状态的
17             res+=dp(jz,pos-1,state,1,limit&&i==w[pos]);//曾经忘记写limit&&
18         else
19             res+=dp(jz,pos-1,state^(1<<i),0,limit&&i==w[pos]);
20     return limit?res:(ans[jz][pos][state][pre0]=res);
21 }
22 LL get(LL b,LL x)
23 {
24     LL g;
25     for(g=0;x>0;x/=b)    w[++g]=x%b;
26     return dp(b,g,0,1,1);//这一种的返回的直接就是1-x的总答案
27 }
28 int main()
29 {
30     memset(ans,-1,sizeof(ans));
31     scanf("%I64d",&q);
32     while(q--)
33     {
34         scanf("%I64d%I64d%I64d",&b,&l,&r);
35         printf("%I64d\n",get(b,r)-get(b,l-1));
36     }
37     return 0;
38 }

2.

 1 #include<cstdio>
 2 #include<cstring>
 3 typedef long long LL;
 4 LL q,b,l,r;
 5 LL ans[11][70][2049];
 6 LL w[70];
 7 //ans[i][j][state][k]:i进制,i进制下j长度,状态为state,k表示是否处于前导0
 8 //状态为0-b-1的数字出现奇数/偶数次
 9 LL dp(LL jz,LL pos,LL state,bool pre0,bool limit)//pre0表示当前位的前一位是不是0
10 {
11     if(pos<1)    return !state;//只有状态全0也就是所有数字出现偶数次才有1个答案
12     if(!limit&&!pre0&&ans[jz][pos][state]!=-1)
13         return ans[jz][pos][state];
14     LL i,res=0,start=pre0?1:0,end=limit?w[pos]:(jz-1);//当前位上界,limit为0表示前面某一位已经取了不是最高值,那么后面的位可以取0-9
15     for(i=start;i<=end;i++)
16         res+=dp(jz,pos-1,state^(1<<i),0,limit&&i==w[pos]);
17     if(!limit&&!pre0)
18         ans[jz][pos][state]=res;
19     return res;
20 }
21 LL get(LL b,LL x)
22 {
23     LL g,i,ret=0;
24     for(g=0;x>0;x/=b)    w[++g]=x%b;
25     for(i=g;i>=1;i--)    ret+=dp(b,i,0,1,i==g);//如果总位数不到g,那么显然所有数字都可以随便取
26     return ret;//这一种的dp返回的是0(1)-x的数中i位的数满足条件的答案
27 }
28 int main()
29 {
30     memset(ans,-1,sizeof(ans));
31     scanf("%I64d",&q);
32     while(q--)
33     {
34         scanf("%I64d%I64d%I64d",&b,&l,&r);
35         printf("%I64d\n",get(b,r)-get(b,l-1));
36     }
37     return 0;
38 }

3.

posted @ 2017-09-29 12:34  hehe_54321  阅读(477)  评论(0编辑  收藏  举报
AmazingCounters.com