• 数学拆分问题--贪心与乘法逆元


    题目链接
    题意:给一个x数,可以将他拆成多个整数,并且这些整数互不相同,使得累积和最大,求累积和最大,最后取模1e9+7

    题解:思考:如果将x拆成多个2的话会让答案值最大,然后再拆成三,再拆成4.....以此类推
    要使答案最大可以从2 3 4 5 ....一直枚举下去,然后将剩余的k值对前面的进行遍历累加,当出现某个数a+k没有与之前重复时,这样会保证答案最大

    先预处理出前缀积,然后将符合条件前缀积除去a,乘上a+k
    除法因为出现取模情况,转为乘法逆元
    乘法逆元:

    ll ext_gcd(ll a,ll b,ll &x,ll &y)
    {
    	ll t,d;
    	if(b==0) {x=1;y=0;return a;
    	}
    	d=ext_gcd(b,a%b,x,y);
    	t=x;
    	x=y;
    	y=t-a/b*y;
    	return d;
    }
    ll Invmod(ll a)
    {
    	ll x,y;
    	if(ext_gcd(a,mod,x,y)!=1) return -1;
    	return (x%mod+mod)%mod;
    }
    

    他人题解博客

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define pb push_back
    ll sum[100005];
    ll mult[100005];
    const ll mod = 1e9+7;
    ll ext_gcd(ll a,ll b,ll &x,ll &y)
    {
    	ll t,d;
    	if(b==0) {x=1;y=0;return a;
    	}
    	d=ext_gcd(b,a%b,x,y);
    	t=x;
    	x=y;
    	y=t-a/b*y;
    	return d;
    }
    ll Invmod(ll a)
    {
    	ll x,y;
    	if(ext_gcd(a,mod,x,y)!=1) return -1;
    	return (x%mod+mod)%mod;
    }
    int main()
    {
    	ll x,i;
    	int t;
    	sum[1]=0,mult[1]=1;
    	for(i=2;i<100005;i++)
    	{
    		sum[i]=sum[i-1]+i;
    	}
    	for(i=2;i<100005;i++)
    	{
    		mult[i]=mult[i-1]*i%mod;
    	}
    	scanf("%d",&t);
    	while(t--)
    	{
    		ll k=0,st=0,i=0;
    		scanf("%d",&x);
    		if(x==1){printf("%d
    ",x);continue;
    		}
    		i=upper_bound(sum+1,sum+100005,x)-sum;
    	 	k=x-sum[i-1];
    	  	st=i-1;
    		i=2;
    		while(1)
    		{
    			if(k+i>st)
    			{		
    				break;
    			}
    			i++;
    		}
    		ll ans=(mult[st]*Invmod(i)%mod)*(k+i)%mod;
    		printf("%lld
    ",ans);
    	}
    	return 0;
    } 
    
  • 相关阅读:
    matplotlib基础
    numpy基础
    池化层的前向计算
    卷积神经网络应用于MNIST数据集分类
    用tensorflow的Eager执行模式
    tensorboard网络结构
    优化器
    交叉熵
    [webpack]——loader配置
    [webpack]--webpack 如何解析代码模块路径
  • 原文地址:https://www.cnblogs.com/q1076452761/p/8033988.html
Copyright © 2020-2023  润新知