zoukankan      html  css  js  c++  java
  • bzoj 3209 花神的数论题

    题目大意:

    设 sum(i)表示i的二进制表示中1的个数

    给出一个正整数N,求是sum(1)—sum(N)的乘积

    思路:

    可以想到对sum的值求有多少个 然后快速幂

    枚举sum的值 使用数位dp

    每遇到一位1 则可以求出小于这位1所有的对于这个sum的组合数

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<queue>
     9 #define inf 2139062143
    10 #define ll long long
    11 #define MAXN 200100 
    12 #define MOD 10000007
    13 using namespace std;
    14 inline ll read()
    15 {
    16     ll x=0,f=1;char ch=getchar();
    17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    19     return x*f;
    20 }
    21 ll n,c[80][80],g[80],cnt,ans;
    22 ll calc(int x)
    23 {
    24     ll res=0;
    25     for(int i=cnt;i&&x>=0&&i-1>=x;i--)
    26         if(g[i]) res+=c[i-1][x--];
    27     return res;
    28 }
    29 ll q_pow(ll bas,ll t)
    30 {
    31     ll res=1;
    32     for(;t;t>>=1,(bas*=bas)%=MOD)
    33         if(t&1) (res*=bas)%=MOD;
    34     return res;
    35 }
    36 int main()
    37 {
    38     n=read()+1,ans=1,c[0][0]=1;
    39     for(int i=1;i<=60;i++)
    40         for(int j=c[i][0]=1;j<=i;j++) c[i][j]=c[i-1][j-1]+c[i-1][j];
    41     while(n) g[++cnt]=n&1,n>>=1;
    42     for(int i=1;i<=cnt;i++)
    43         (ans*=q_pow(i,calc(i)))%=MOD;
    44     printf("%lld
    ",ans);
    45 }
    View Code
  • 相关阅读:
    如何描述一个前端开发程序员
    解决电脑性能一般,打开webstorm后,电脑比较卡的问题
    HTML5的5个的新特性
    js 数组的拼接
    移动端性能
    如何学习前端
    实战:上亿数据如何秒查
    读懂Java中的Socket编程
    远程管理软件
    dedecms 安装后 管理后台ie假死 无响应的解决方法
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/9868728.html
Copyright © 2011-2022 走看看