zoukankan      html  css  js  c++  java
  • 失格

    Description

    胆小鬼连幸福都会害怕,碰到棉花都会受伤,有时还被幸福所伤。
    ——太宰治《人间失格》

    回顾我的一生,一共有n个事件,每一个事件有一个幸福值pi。
    我想用n-1条线把所有的事件连起来,变成一个连通块。一条连接了事件x和事件y的线会产生min(px mod py , py mod px)的喜悦值。
    日日重复同样的事,遵循着与昨日相同的惯例,若能避开猛烈的狂喜,自然也不会有悲痛的来袭。因此,我想知道连接起来之后产生喜悦值最小是多少。

    solution

    比较简单的题,注意到边权是固定的,设点权较大的为 (i),较小的为 (j),边权即为 (a[i]\%a[j]),容易发现 (a[j]+1)(a[j]+2) 要更优,所以可以忽略掉很多没用的边,对于大于 (a[j]) 的每一个倍数取出最小的一个即可,我们可以二分求解,注意到这样是会被卡的,需要unique一遍,因为这样最坏复杂度就变成了 (sum{a[n]/i}),要记住这个复杂度是 (O(n*In_{n}))的,边数也是一样,然后跑kruskal即可

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    typedef long long ll;
    const int N=100005;
    int n,a[N],fa[N];
    inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    
    inline int midit(int l,int x){
    	int r=n,mid,ret=-1;
    	while(l<=r){
    		mid=(l+r)>>1;
    		if(a[mid]>=x)ret=mid,r=mid-1;
    		else l=mid+1;
    	}
    	return ret;
    }
    
    struct node{
    	int x,y,dis;
    	node(){}
    	node(int _x,int _y,int _dis){x=_x;y=_y;dis=_dis;}
    	bool operator <(const node &pr)const{return dis<pr.dis;}
    }e[N*20];
    
    void work()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    	sort(a+1,a+n+1);
    	n=unique(a+1,a+n+1)-a-1;
    
    	int x,y,tot=0,cnt=0;ll ans=0;
    	for(int i=1;i<n;i++){
    		fa[i]=i;
    		for(int j=a[i];j<=a[n];j+=a[i]){
    			x=midit(i+1,j);
    			if(x==-1)break;
    			e[++tot]=node(i,x,a[x]%a[i]);
    		}
    	}
    	fa[n]=n;
    	sort(e+1,e+tot+1);
    	for(int i=1;i<=tot;i++){
    		x=e[i].x;y=e[i].y;
    		if(find(x)==find(y))continue;
    		fa[find(y)]=find(x);
    		ans+=e[i].dis;
    		cnt++;
    		if(cnt==n-1)break;
    	}
    	printf("%lld
    ",ans);
    }
    
    int main()
    {
    	work();
    	return 0;
    }
    
    
  • 相关阅读:
    Java实现 LeetCode 735 行星碰撞(栈)
    Java实现 LeetCode 735 行星碰撞(栈)
    Java实现 LeetCode 887 鸡蛋掉落(动态规划,谷歌面试题,蓝桥杯真题)
    Java实现 LeetCode 887 鸡蛋掉落(动态规划,谷歌面试题,蓝桥杯真题)
    Java实现 LeetCode 887 鸡蛋掉落(动态规划,谷歌面试题,蓝桥杯真题)
    Java实现 蓝桥杯算法提高 求最大值
    Java实现 蓝桥杯算法提高 求最大值
    Java实现 蓝桥杯算法提高 求最大值
    Python eval() 函数
    Python repr() 函数
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7807929.html
Copyright © 2011-2022 走看看