• HDU 5976 Detachment


     
    这道题目是向这位博主学习的,链接贴出来:☆HDU 5976 Detachment 详细题解(贪心+逆元+前缀和,积),讲的很细致,很感谢;

    思路:

    1.题意是将数x分成若干个正整数和,使得这些整数的乘积最大,并求出这个最大乘积除以1e9+7的余数;
    2.要使得乘积最大,那么我们需要尽可能的分出更多的数(1除外),又因为分出的数需要各不相同,由贪心思想,我们可以从最小的2开始往后分,一直分到k,这个k满足:(1)2+3+4+...+k<=x(2)2+3+4+...+(k+1)>x
    我们记前缀和数组sum[i]=2+3+...+i,记ans=x-sum[k]
    我们可以知道ans>=0&&ans<=k
    3.此时我们已经将数大致分好,还差ans、和就可以达到x,此时的想法是将ans分成若干个1从后往前摊派到各个数上(如果从前往后摊派会造成数据重复),摊派完会根据ans值的不同而出现两种情况:
    (我们设f(x)x1e9+7的逆)
    (1)ans>=0&&ans<k
    此时乘积是2*3*4*...*(r-1)*(r+1)*...*(k+1)
    答案是(k+1)!/r%MOD,即(k+1)!*f(r)%MOD
    (2)ans==k
    此时乘积是3*4*5*...*k*(k+2)
    答案是(k+2)!/(k+1)/2%MOD,即 (k+2)!*f(k+1)*f(2)%MOD;

    代码:

    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    const int MAX_N=1e5;
    const LL MOD=1e9+7;
    LL mul[MAX_N],sum[MAX_N];      //前缀积、前缀和 
    LL extgcd(LL a,LL b,LL& x,LL& y){
    	LL d=a;
    	if(b){d=extgcd(b,a%b,y,x);y-=(a/b)*x;}
    	else{x=1;y=0;}
    	return d;
    }
    LL mod_inv(LL a,LL m){
    	LL x,y;
    	extgcd(a,m,x,y);
    	return (m+x%m)%m;
    }
    void init(){
    	mul[1]=1;
    	for(int i=2;i<MAX_N;i++) mul[i]=mul[i-1]*i%MOD;
    	for(int i=2;i<MAX_N;i++) sum[i]=sum[i-1]+i;
    } 
    int main(){
    	init();
    	int t;
    	LL x;
    	scanf("%d",&t);
    	while(t--){
    		scanf("%lld",&x);
    		if(x==1){puts("1");continue;}
    		int k=(upper_bound(sum,sum+MAX_N,x)-sum)-1;
    		LL ans=x-sum[k];
    		if(ans<k){
    			LL r=k-ans+1;
    			printf("%lld
    ",mul[k+1]*mod_inv(r,MOD)%MOD);
    		}else{
    			printf("%lld
    ",mul[k+2]*mod_inv(k+1,MOD)%MOD*mod_inv(2,MOD)%MOD);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    怎样用javascript关闭本窗口
    ASP.NET 3.5控件和组件开发技术之客户端回发/回调揭密
    谈谈"求线段交点"的几种算法(js实现,完整版)
    您是哪个等级的CSS开发人员?
    使用CSS3创建文字颜色渐变(CSS3 Text Gradient)
    拦截asp.net输出流做处理
    ASP.NET读取RSS
    简单高效的asp.net目录树源代码
    使用HTML5、CSS3和jQuery增强网站用户体验[留存]
    ASP.NET中的加密页面机制
  • 原文地址:https://www.cnblogs.com/yuhan-blog/p/12308836.html
Copyright © 2020-2023  润新知