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

    洛咕

    题意:设( ext{sum}(i))表示(i)的二进制表示中(1)的个数.给出一个正整数(N),求(prod_{i=1}^{N} ext{sum}(i)),也就是 ( ext{sum}(1)sim ext{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
    ",part(n));
        return 0;
    }
    
    
  • 相关阅读:
    ulimit
    python3.7安装Scrapy
    用VS2013写第一个汇编语言程序
    螺旋矩阵问题
    Java Web Pro与apache tomcat初始化关联
    记一次m3u8多个视频文件合并为整体法四(未加密)
    记一次m3u8多个视频文件合并为整体法三(未加密)
    记一次m3u8多个视频文件合并为整体法二(未加密)
    记将m3u8多个视频文件合并为整体法一(未加密)
    c++给定字符分割
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11586849.html
Copyright © 2011-2022 走看看