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

    3209: 花神的数论题

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1893  Solved: 866
    [Submit][Status][Discuss]

    Description

    背景
    众所周知,花神多年来凭借无边的神力狂虐各大 OJ、OI、CF、TC …… 当然也包括 CH 啦。
    描述
    话说花神这天又来讲课了。课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了。
    花神的题目是这样的
    设 sum(i) 表示 i 的二进制表示中 1 的个数。给出一个正整数 N ,花神要问你
    派(Sum(i)),也就是 sum(1)—sum(N) 的乘积。

    Input

    一个正整数 N。

    Output

    一个数,答案模 10000007 的值。

    Sample Input

    样例输入一

    3

    Sample Output

    样例输出一

    2

    HINT



    对于样例一,1*1*2=2;


    数据范围与约定


    对于 100% 的数据,N≤10^15

    Source

    [Submit][Status][Discuss]

    花神系列出好题

    显然应该枚举1的个数,计算有多少个小于等于N的数字,其中含有这么多的1。

    这个显然就是数位DP了是吧,注意开个全局long long比较保险省心。

     1 #include <cstdio>
     2 
     3 #define int long long
     4 
     5 const int siz = 65;
     6 const int mod = 10000007;
     7 
     8 inline int pow(int a, int b)
     9 {
    10     int ret = 1;
    11     
    12     for (; b; b >>= 1)
    13     {
    14         if (b & 1)
    15         {
    16             ret *= a;
    17             if (ret >= mod)
    18                 ret %= mod;
    19         }
    20         
    21         a *= a;
    22         if (a >= mod)
    23             a %= mod;
    24     }
    25     
    26     return ret;
    27 }
    28 
    29 int n;
    30 int len;
    31 int ans = 1;
    32 int f[siz][siz];
    33 
    34 inline int count(int t)
    35 {
    36     int ret = 0;
    37     
    38     for (int i = len - 1; ~i && ~t; --i) 
    39         if ((n >> i) & 1)ret += f[i][t--];
    40     
    41     return ret;
    42 }
    43 
    44 signed main(void)
    45 {
    46     scanf("%lld", &n); ++n;
    47     
    48     for (int i = 0; i < siz; ++i)
    49         f[i][0] = 1;
    50     
    51     for (int i = 1; i < siz; ++i)
    52         for (int j = 1; j <= i; ++j)
    53             f[i][j] = f[i - 1][j] + f[i - 1][j - 1];
    54             
    55     while (n >> len)++len;
    56     
    57     for (int i = 2; i <= len; ++i)
    58         (ans *= pow(i, count(i))) %= mod;
    59     
    60     printf("%lld
    ", ans);
    61 }

    @Author: YouSiki

  • 相关阅读:
    CSS实现返回网页顶部
    jQuery实现小火箭动态返回顶部代码
    Linux目录结构介绍
    Linux常用命令及技巧
    Linux文件系统
    Linux特性
    numpy中基础函数
    restful规范
    堆栈
    三次握手与四次挥手
  • 原文地址:https://www.cnblogs.com/yousiki/p/6297995.html
Copyright © 2011-2022 走看看