zoukankan      html  css  js  c++  java
  • 种树

    https://zybuluo.com/ysner/note/1228915

    题面

    一个有(n)个点的带点权环,最大化选取(m)个不相邻的点得到的权值。

    • (nleq2*10^5)

    解析

    显然可以贪心。
    大根堆维护所有点权值。
    每次堆顶点,同时把反悔选相邻点的影响(a[L[u]]+a[R[u]]-a[u]))塞入堆中,并标记相邻两点不可

    有点卡壳的操作是把(a[u]=a[L[u]]+a[R[u]]-a[u])
    实际上是因为,如果反悔了,这样能使(a[u])变为初始值。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #define re register
    #define il inline
    #define ll long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define fp(i,a,b) for(re int i=a;i<=b;i++)
    #define fq(i,a,b) for(re int i=a;i>=b;i--)
    using namespace std;
    const int N=5e5+100;
    struct dat{int w,id;bool operator < (const dat&o) const {return w<o.w;}};
    int n,m,a[N],L[N],R[N],vis[N];
    ll ans;
    priority_queue<dat>Q;
    il ll gi()
    {
      re ll x=0,t=1;
      re char ch=getchar();
      while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
      if(ch=='-') t=-1,ch=getchar();
      while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
      return x*t;
    }
    il void Del(re int u){L[R[u]]=L[u];R[L[u]]=R[u];}
    int main()
    {
    	n=gi();m=gi();
    	if(n/2<m) {puts("Error!");return 0;} 
    	fp(i,1,n) a[i]=gi();
    	fp(i,1,n) L[i]=i+1,R[i]=i-1;L[n]=1;R[1]=n;
    	fp(i,1,n) Q.push((dat){a[i],i});
    	while(m--)
    	{
    		while(vis[Q.top().id]) Q.pop();
    		re dat u=Q.top();Q.pop();
    		ans+=u.w;
    		a[u.id]=a[L[u.id]]+a[R[u.id]]-u.w;
    		Q.push((dat){a[u.id],u.id});
    		vis[L[u.id]]=vis[R[u.id]]=1;
    		Del(L[u.id]);Del(R[u.id]);
    	}
        printf("%lld
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    sss
    stm32cube使用
    FreeRTOS
    嵌入式网站
    CRC分段校验
    IAR编译器
    (转)UCOSII源代码剖析
    (转)stm32硬件IIC
    keil MDK注意事项
    (转).Net中自定义类作为Dictionary的key详解
  • 原文地址:https://www.cnblogs.com/yanshannan/p/9378083.html
Copyright © 2011-2022 走看看