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

    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

    正解:数位$dp$。

    数位$dp$水题。设$f[i][j][k]$表示前$i$位,二进制和为$j$,当前这位有没有限制的答案。

    直接用记忆化搜索转移即可。

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 #define rhl (10000007)
     6 
     7 using namespace std;
     8 
     9 int f[70][70][2],st[70],top;
    10 ll n;
    11 
    12 il int gi(){
    13   RG int x=0,q=1; RG char ch=getchar();
    14   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    15   if (ch=='-') q=-1,ch=getchar();
    16   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    17   return q*x;
    18 }
    19 
    20 il int dfs(RG int pos,RG int tot,RG int lim){
    21   if (!pos) return tot?tot:1;
    22   if (f[pos][tot][lim]!=-1) return f[pos][tot][lim];
    23   RG int end=lim?st[pos]:1,&res=f[pos][tot][lim]; res=1;
    24   for (RG int i=0;i<=end;++i)
    25     res=1LL*res*dfs(pos-1,tot+i,lim && i==end)%rhl;
    26   return res;
    27 }
    28 
    29 int main(){
    30 #ifndef ONLINE_JUDGE
    31   freopen("god.in","r",stdin);
    32   freopen("god.out","w",stdout);
    33 #endif
    34   cin>>n; memset(f,-1,sizeof(f));
    35   while (n) st[++top]=n&1,n>>=1;
    36   cout<<dfs(top,0,1); return 0;
    37 }
  • 相关阅读:
    《程序员修炼之道:从小工到专家》阅读笔记02
    第二阶段团队冲刺10
    第二阶段团队冲刺09
    周总结
    第二阶段团队冲刺08
    第二阶段团队冲刺07
    小A和小B和幽灵追两人(双向BFS)
    C. 真假亚瑟王(暴力)
    小A的柱状图(栈的应用,找左右边界)
    小A买彩票
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7769018.html
Copyright © 2011-2022 走看看