zoukankan      html  css  js  c++  java
  • bzoj3209 花神的数论题 (二进制数位dp)

    二进制数位dp,就是把原本的数字转化成二进制而以,原来是10进制,现在是二进制来做,没有想像的那么难

    不知到自己怎么相出来的。。。感觉,如果没有一个明确的思路,就算做出来了,也并不能锻炼自己的能力,因为我现在需要训练的是做题的思维方法啊!

    sum(i) 表示 i 的二进制表示中 1 的个数。给出一个正整数 N ,求sum(1)—sum(N) 的乘积。

    首先,这道题直接做,感觉无从下手,那么我就想,怎么来转换一下,求1~n中每个数的一的个数总相乘之积,首先感觉到,每个数都会有唯一对应的1的个数,且一的个数的取值只有最多60,因为n最大   10^15,  那么我就想,如果枚举1的个数k,计算有多少个数含有k个1,(因为数位dp就是来做,有多少满足的数,且不关注数的大小)这样就转化为数位dp的模型了

    另外,发现含有k个1的数个数可能非常多,快速幂搞一搞啦,

    不过快速幂要注意超long long 的情况!!,因为在很多题mod比较大,mod<根号2^31,平方之后就有可能超int!!!!!

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath> 
     5 #include<algorithm>
     6 using namespace std;
     7 
     8 typedef long long int ll;
     9 const int MAXN=60+5;
    10 const ll mod=10000007;
    11 
    12 ll n,Ans;
    13 ll c[MAXN][MAXN];
    14 int l,wei[MAXN];
    15 void pre()
    16 {
    17     for (int i=0;i<=60;++i)
    18       c[i][0]=1;
    19     for(int i=1;i<=60;i++)
    20       for(int j=1;j<=i;++j)
    21         c[i][j]=c[i-1][j-1]+c[i-1][j];//c[i][j]表示i位,j个1。 
    22     scanf("%lld",&n);
    23     l=0,n+=1;//只能计算小于n的个数,所以要加1
    24     while(n)
    25     {
    26       wei[++l]=n&1;
    27       n>>=1;
    28     }//将n转换为2进制。 
    29 }
    30 ll Solve(int x)//解决有x个1的方案数 
    31 {
    32     ll sum=0;
    33     for (int i=l;i>=1;--i)
    34     {
    35       if(wei[i]==1)
    36       {
    37         sum+=c[i-1][x];
    38         x--; 
    39       }
    40       if(x<0) break;
    41     }
    42     return sum;
    43 }
    44 ll Pow(ll a, ll b){
    45     ll tot=1;
    46     a%=mod;
    47     while(b)
    48     {
    49       if(b&1)
    50       {
    51         tot=a*tot%mod;
    52         tot%=mod;
    53       }
    54       b>>=1;a*=a;a%=mod;
    55     }
    56     return tot;
    57 }
    58 int main()
    59 {
    60     pre();
    61     Ans=1ll;
    62     for(int i=1;i<=l;++i)
    63       Ans=Ans*Pow(i,Solve(i))%mod;
    64     printf("%lld
    ",Ans);
    65     return 0;
    66 }
  • 相关阅读:
    MD5工具类
    新搭建mysql容易出现问题
    docker自动化部署
    k8s入门案例
    docker单一部署jenkins
    Sentinel 学习-简介
    mysql innerjoin,leftjoin,group by,having
    批量更新 分割list 多线程处理
    redis 3.0+ cluser 集群搭建
    ELK 和 Logstach
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7444592.html
Copyright © 2011-2022 走看看