首页 > 其他 > 详细

花神的数论题

时间:2019-09-25 20:04:36      阅读:94      评论:0      收藏:0      [点我收藏+]

洛咕

题意:设\(\text{sum}(i)\)表示\(i\)的二进制表示中\(1\)的个数.给出一个正整数\(N\),求\(\prod_{i=1}^{N}\text{sum}(i)\),也就是 \(\text{sum}(1)\sim\text{sum}(N)\)的乘积.\(N<=10^{15}.\)

分析:做完同类分布之后再做的这题,所以一下就想到了要枚举 二进制表示中含\(1\)的个数,然后分别求有多少个.

一开始想错结论了,就把每次\(dfs\)的结果都累乘起来,发现答案基本上都是零.假设我们当前枚举的是二进制表示中含\(1\)的个数有\(sum\)个,然后有\(x\)个这样的数,则此次的贡献是\(sum^x\).

对于模数\(1e7+7\),好像这不是个质数,\(1e7+7=941*10627\),但是好像不用管这个,还是照常取模就行了.是因为数据水么\(???\)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define ll long long
using namespace std;
inline ll read(){
    ll x=0,o=1;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')o=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*o;
}
const int mod=10000007;
int len,a[60];ll ans=1,dp[60][60][60];
inline ll dfs(int pos,int pre,int sum,int lead,int limit,int goal){
    if(pos>len)return sum==goal;
    if(sum>goal)return 0;//剪枝:如果1的个数超过了当前枚举
    if(dp[pos][pre][sum]!=-1&&!lead&&!limit)return dp[pos][pre][sum];
    ll cnt=0;int res=limit?a[len-pos+1]:1;
    for(int i=0;i<=res;++i){
        if((!i)&&lead)cnt+=dfs(pos+1,0,0,1,limit&&(i==res),goal);
        else if(i&&lead)cnt+=dfs(pos+1,i,(i==1),0,limit&&(i==res),goal);
        else cnt+=dfs(pos+1,i,sum+(i==1),0,limit&&(i==res),goal);
    }
    return !lead&&!limit?dp[pos][pre][sum]=cnt:cnt;
}
inline ll ksm(ll a,ll b){
    ll cnt=1;
    while(b){
        if(b&1)cnt=(1ll*cnt*a)%mod;
        a=(1ll*a*a)%mod;
        b>>=1;
    }
    return cnt;
}
inline ll part(ll x){
    len=0;while(x)a[++len]=x&1,x>>=1;//拆成二进制表示
    for(int sum=1;sum<=len;++sum){//枚举含1的个数
        memset(dp,-1,sizeof(dp));
        ans=(1ll*ans*ksm(sum,dfs(1,0,0,1,1,sum)))%mod;//统计答案
    }
    return ans;
}
int main(){
    ll n=read();printf("%lld\n",part(n));
    return 0;
}

花神的数论题

原文:https://www.cnblogs.com/PPXppx/p/11586849.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!