• [CSP-S模拟测试]:Six(数学)


    题目传送门(内部题85)


    输入格式

    一个正整数$N$。


    输出格式

    一个数表示答案对$1000000007$取模后的结果


    样例

    样例输入1:

    6

    样例输出1:

    28

    样例输入2:

    203021

    样例输出2:

    33628

    样例输入3:

    60357056536

    样例输出3:

    907882

    样例输入4:

    12156144

    样例输出4:

    104757552


    数据范围与提示

    样例解释:

    第一组样例:${(2),(2,2),(2,2,3),(2,2,3,3),(2,3),(2,3,2),(2,3,2,3),(2,3,3),(2,3,3,2),(2,6),(2,6,3),(3),(3,2),(3,2,2),(3,2,2,3),(3,2,3),(3,2,3,2),(3,3),(3,3,2),(3,3,2,2),(3,6),(3,6,2),(6),(6,2),(6,2,3),(6,3),(6,3,2),(6,6)}$

    数据范围:

    对于$32\%$的数据,$N$最多有$2$个不同的质因数
    对于$56\%$的数据,$N$最多有$4$个不同的质因数
    对于$100\%$的数据,$Nleqslant 10^{15}$且$N$最多有$6$个不同的质因数


    题解

    爆搜能有一半的分,在加上记忆化就$A$了……

    记录一下二进制位下每一位$1$的个数状态,但是注意$1$可以是两个,所以还需要再开一个数记录一下是否已经达到了两个。

    队列里的数最多只有$12$个,所以状态数也不多,$50,000$以内,用$map$记录就好了。

    时间复杂度:$Theta(sqrt{N}+50,000)$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    const int mod=1000000007;
    map<pair<long long,long long>,int>dp;
    long long N;
    long long d[1001],fla[1001],top;
    pair<long long,int> pri[10];
    long long dfs(int x,long long res1,long long res2)
    {
    	if(dp[make_pair(res1,res2)])return dp[make_pair(res1,res2)];
    	dp[make_pair(res1,res2)]=1;
    	for(int i=1;i<(1<<top);i++)
    	{
    		int sum=0;bool flag=0;
    		for(int j=1;j<(1<<top);j++)
    		{
    			if(!(i&j))continue;
    			if((res1>>j)&1)sum++;
    			if((res2>>j)&1)flag=1;
    			if(flag||sum>1)goto nxt;
    		}
    		if((res1>>i)&1)dp[make_pair(res1,res2)]=(dp[make_pair(res1,res2)]+d[i]*dfs(x+1,res1^(1LL<<i),res2|(1LL<<i))%mod)%mod;
    		else dp[make_pair(res1,res2)]=(dp[make_pair(res1,res2)]+d[i]*dfs(x+1,res1|(1LL<<i),res2)%mod)%mod;
    		nxt:;
    	}
    	return dp[make_pair(res1,res2)];
    }
    int main()
    {
    	scanf("%lld",&N);
    	for(long long i=2;i*i<=N;i++)
    		if(!(N%i))
    		{
    			pri[++top].first=i;
    			while(!(N%i))
    			{
    				pri[top].second++;
    				N/=i;
    			}
    		}
    	if(N!=1)pri[++top]=make_pair(N,1);
    	d[0]=1;
    	for(int i=1;i<=top;i++)fla[1<<i-1]=i;
    	for(int i=1;i<(1<<top);i++)d[i]=d[i^(i&-i)]*pri[fla[i&-i]].second;
    	printf("%lld
    ",dfs(0,0,0)-1);
    	return 0;
    }
    

    rp++

  • 相关阅读:
    vsftp 虚拟用户测试
    RHEL7 MariaDB测试
    安装xenapp后,非管理员连接RDP出现桌面当前不可用的解决方法
    sqrt函数的实现
    O2O、C2C、B2B、B2C
    libsvm使用说明
    如何确定最适合数据集的机器学习算法
    知乎日报:她把全世界的学术期刊都黑了
    逻辑回归应用之Kaggle泰坦尼克之灾
    非均衡数据分布的分类问题
  • 原文地址:https://www.cnblogs.com/wzc521/p/11736874.html
Copyright © 2020-2023  润新知