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

    定义(sum(i))表示(i)在二进制下(1)的个数

    (prod_{i=1}^{n}sum(i))

    暴力非常(sb)显然可以随便写,但是显然也是会(T)

    于是我们换个思路

    我们设(tot)表示(sum(i)=x)(i)有多少个,于是答案就是(x^{tot})

    我们枚举(x)就行了,(x)显然不会很大,也就是(log_2{n})

    之后就可以开始数位(dp)

    我们设(dp[i][0/1][j])表示最高位填到第(i)位,其中最高位填(0/1),一共填了(j)个1一共有多少个数

    方程很显然,就是往最高位上填(0/1)

    填0的话

    [dp[i+1][0][j]+=dp[i][1][j]+dp[i][0][j] ]

    填1的话

    [dp[i+1][1][j+1]+=dp[i][0][j]+dp[i][1][j] ]

    之后我们按照数位(dp)的套路来做就行了

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define LL long long 
    #define re register
    #define maxn 55
    const LL mod=10000007;
    const LL P=9988440;
    LL n;
    int a[maxn];
    LL dp[maxn][2][maxn];
    inline LL quick(LL a,LL b)
    {
    	LL S=1;
    	while(b)
    	{
    		if(b&1) S=S*a%mod;
    		b>>=1ll;
    		a=a*a%mod;
    	}
    	return S;
    }
    inline LL sum(LL x)
    {
    	LL cnt=0;
    	while(x)
    	{
    		if(x&1ll) cnt++;
    		x>>=1ll;
    	}
    	return cnt;
    }
    inline LL slove(LL x)
    {
    	int num=0;
    	while(x)
    	{
    		++num;
    		if(x&1ll) a[num]=1;
    		x>>=1ll;
    	}//分解数位
    	dp[1][1][1]=1;
    	dp[1][0][0]=1;
    	for(re int i=1;i<num;i++)
    		for(re int j=0;j<=i;j++)
    		{
    			dp[i+1][1][j+1]=(dp[i+1][1][j+1]+dp[i][0][j]+dp[i][1][j]);
    			dp[i+1][0][j]=(dp[i+1][0][j]+dp[i][0][j]+dp[i][1][j]);
    		}//dp的过程
    	LL ans=1;
    	for(re int T=1;T<=num;T++)//枚举T求出有多少i,sum(i)=T
    	{
    		for(re int i=1;i<num;i++)
    			ans=(ans*quick(T,dp[i][1][T])%mod)%mod;
            //先枚举位数比n要小的
    		int k=T;
    		if(a[num]) k--;
    		for(re int i=num-1;i>=1;i--)//之后我们卡前面的[i+1,num]为完全相等,让第i位小于n的第i位,我们就可以让后面的位数随便填了
    		{
    			for(re int j=0;j<a[i];j++)
    				ans=(ans*quick(T,dp[i][j][k])%mod)%mod;
    			if(a[i]) k--;//别忘了保证前面的数位相等,要减去前面1的个数
    			if(k<0) break;
    		}
    	}
    	return ans;
        //由于一直在卡上界,但最后也没有卡到等于n的情况,于是n的暴力分解数位处理一下就好了
    }
    int main()
    {
    	scanf("%lld",&n);
    	std::cout<<sum(n)*slove(n)%mod;
    	return 0;
    }
    
  • 相关阅读:
    java.lang.ClassCastException: java.util.HashMap$Values cannot be cast to java.util.List 转换异常
    React Swiper轮播图(二)
    超详细带你入门开发一个超实用的浏览器插件
    手臂太细如何增加纬度?这5个手臂锻炼动作,让你的手臂变粗壮
    2021百度世界大会精华总结(AI应用向)
    1、saltstack 安装部署
    MySQL的varchar(10)能存多少个汉字
    学习资料总结
    基于Spark的数据工厂(Data Factory):从设计到实现
    IntelliJ IDEA创建maven web项目(IDEA新手适用)
  • 原文地址:https://www.cnblogs.com/asuldb/p/10206207.html
Copyright © 2011-2022 走看看