zoukankan      html  css  js  c++  java
  • Jzoj5445【NOIP2017提高A组冲刺11.2】失格

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

     
    回顾我的一生,一共有n个事件,每一个事件有一个幸福值p_i。
    我想用n-1条线把所有的事件连起来,变成一个连通块。一条连接了事件x和事件y的线会产生min(p_x mod p_y,p_y mod p_x)的喜悦值。

    日日重复同样的事,遵循着与昨日相同的惯例,若能避开猛烈的狂喜,自然也不会有悲痛的来袭。因此,我想知道连接起来之后产生喜悦值最小是多少

    对于30%的数据,保证1<=n<=10^3。
    对于另外40%的数据,保证1<=p_i<=10^6。
    对于100%的数据,保证1<=n<=10^5,1<=p_i<=10^7。

    给你n个点叫你求一个最小生成树

    考虑贪心,我们先将所有的p排序去重(显然代价为0),让后对于每一个pi,枚举它的倍数kpi

    我们对于每一个kpi找到一个比其大而且最小的pj,我们将i->j连一条边,边权为pj-kpi

    让后直接跑MST即可

    注意这题虽然有7s+3/4GB内存但是这样是会超时的

    我们考虑两个优化

    1.若pj-kpi>p1(p中最小的) 那么我们不连接i->j

    显然,最坏情况下,我们依然可以每个点都和p[1]连接,这样最长边也会比p[1]要小

    2.在找pj的时候,若有多个k满足p[j-1]<kp<=p[j]那么我们只保留k最大的那个,这里可以用二分加速

    让后就是乱搞的mst即可,注意并查集记得写按秩合并

    (另外不建议看上面开头提到的那部小说!特别针对某些人群,如果你已经进了省队请无视这句话~)

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define M 5000010
    #define N 100010
    #define P 10000000
    using namespace std;
    struct Edge{ int u,v,c; } G[M];
    int n,m,s[N],t=0,f[N],r[N],v[M]; long long p=0;
    inline bool c1(Edge a,Edge b){ return a.c<b.c; }
    inline int gf(int x){ return x==f[x]?x:f[x]=gf(f[x]); }
    inline void merge(int x,int y){
    	if(r[x]>r[y]) f[y]=x;
    	else {
    		f[x]=y;
    		if(r[x]==r[y]) ++r[y];
    	}
    }
    int main(){
    	freopen("autosadism.in","r",stdin);
    	freopen("autosadism.out","w",stdout);
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i) scanf("%d",s+i),f[i]=i,r[i]=1;
    	sort(s+1,s+1+n); n=unique(s+1,s+1+n)-s-1; s[n+1]=1<<30;
    	for(int i=1;i<=n;++i)
    		for(int j=s[i],k=i+1;j<=P&&k<=n;j+=s[i]){
    			if(s[k]<j) k=lower_bound(s+i,s+2+n,j)-s;
    			if(k>n) break; j+=(s[k]-j)/s[i]*s[i];
    			if(s[k]-j<=s[1]) G[t++]=(Edge){i,k,s[k]-j};
    		}
    	sort(G,G+t,c1);
    	for(int u,v,i=0,k=1;k<n;++i){
    		u=gf(G[i].u); v=gf(G[i].v);
    		if(u!=v){ merge(u,v); k++; p+=G[i].c; }
    	}
    	printf("%lld
    ",p);
    }

  • 相关阅读:
    Doubles
    The 3n + 1 problem
    Counterfeit Dollar
    Maya Calendar
    08_python的列表、元祖、字符串、字典及公共方法
    07_python的函数
    06_python的while语句
    05_python的if语句
    04_python基本的输入输出函数
    03_python的数据类型和变量的定义及使用
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/7774310.html
Copyright © 2011-2022 走看看