您的位置:首页 > 其它

BZOJ 3209(花神的数论题-数位统计+1,被数据范围坑了)

2013-05-27 15:11 471 查看

3209: 花神的数论题

Time Limit: 10 Sec Memory Limit: 128 MB

Submit: 33 Solved: 18

[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

原创 Memphis

[Submit][Status][Discuss]


好吧……这题一开始的范围是N<=1015

然后我很天真的以为这不水吗^?结果……

好吧……

之后要来数据以后才发现……

n<=10^15

只有我这种蒟蒻会被这个骗……



被各种D……

Ok,那么这题就是数位统计了……

刚学的……(还在学这个<-弱)

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#include<cmath>
#include<cctype>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define RepD(i,n) for(int i=n;i>=0;i--)
#define MAXN (100000)
#define MAXL (50+10)
#define F (10000007)
int a[MAXN],len=0;
long long C[MAXL][MAXL];
long long n;
long long calc(int k)
{
long long ans=0;
ForD(i,len)
{
if (a[i])
{
ans+=C[i-1][k];
k--;
}
if (k<0) return ans;
}
return ans;
}
long long pow2(long long a,long long b)
{
if (b==0) return 1;
if (b==1) return a;
long long tmp=pow2(a,b/2);
tmp=tmp*tmp%F;
if (b%2) tmp=(tmp*a)%F;
return tmp;
}
int main()
{
//	freopen("flower1.in","r",stdin);
//	freopen(".out","w",stdout);
Rep(i,50)
{
C[i][0]=1;
For(j,i) C[i][j]=(C[i-1][j]+C[i-1][j-1]);
}
/*
cout<<pow2(2,1001)<<endl;
int pp=1;
For(i,1001) pp=(pp*2)%F;cout<<pp;
*/
while (cin>>n)
{
n++;//cout<<n<<endl;
len=0;
while (n) {a[++len]=n%2;n/=2;}
long long ans=1;//cout<<len<<endl;
For(i,len) ans=(ans*pow2(i,calc(i)))%F;
printf("%lld\n",ans);
};
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: