zoukankan      html  css  js  c++  java
  • 「AHOI / HNOI2018」排列(DAG上贪心+堆)

    https://loj.ac/problem/2509

    (a[i]->i)连边,图不是DAG无解,之后就是(p)必须是一个DAG的Turpo序,然后使得(sum i*w[p[i]])最大。

    考虑无论是正着贪心还是反着贪心,都TM有后效性,然后这个题不太能可撤销贪心。

    之后的套路好像在哪里见过类似的,但忘了是在哪里。

    考虑最小的(w[i]),如果它的父亲选了,就一定会马上选它,那么我们可以将它们合并成一段数。

    然后继续选最小的,对于两段数,设和分别为(p1,p2),。个数分别为(q1,q2),发现(p1、q1)在前面更优的条件是(p1*q2<p2*q1->frac{p1}{q1}<frac{p2}{q2})

    那么每一段数的新权值可以设为平均数,需要支持删除和插入和找最小值的数据结构,堆即可。

    还需要用个并查集去合并数。

    Code:

    #include<bits/stdc++.h>
    #define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
    #define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
    #define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
    #define ll long long
    #define pp printf
    #define hh pp("
    ")
    using namespace std;
    
    const int N = 5e5 + 5;
    
    int n, fa[N], w[N];
    int f[N];
    
    int F(int x) { return f[x] == x ? x : (f[x] = F(f[x]));}
    
    ll p[N], q[N], s[N];
    
    int bz[N];
    
    struct P {
    	ll p, q, s; int i;	
    };
    
    bool operator < (P a, P b) {
    	if(a.p * b.q != b.p * a.q) return a.p * b.q < b.p * a.q;
    	return a.i < b.i;	
    }
    
    multiset<P> t;
    
    ll ans, ans2;
    
    int main() {
    	scanf("%d", &n);
    	fo(i, 1, n) scanf("%d", &fa[i]);
    	fo(i, 1, n) scanf("%d", &w[i]);
    	fo(i, 1, n) {
    		f[i] = i;
    		p[i] = w[i], q[i] = 1, s[i] = w[i];
    		t.insert((P) {p[i], q[i], s[i], i});
    	}
    	fo(i, 1, n) {
    		P b = *t.begin(); t.erase(t.begin());
    		if(fa[b.i] == 0) {
    			bz[b.i] = 1;
    			ans += b.p * ans2 + b.s;
    			ans2 += b.q;
    		} else {
    			int x = F(b.i), y = F(fa[b.i]);
    			if(x == y) {
    				pp("-1
    "); return 0;
    			}
    			f[x] = y;
    			if(bz[y]) {
    				ans += b.p * ans2 + b.s;
    				ans2 += b.q;
    				continue;
    			}
    			t.erase(t.find((P) {p[y], q[y], s[y], y}));
    			s[y] += s[x] + p[x] * q[y];
    			p[y] += p[x], q[y] += q[x];
    			t.insert((P) {p[y], q[y], s[y], y});
    		}
    	}
    	pp("%lld
    ", ans);
    }
    
  • 相关阅读:
    2018第45周日
    RabbitMQ消息的消费与持久化
    Rabbitmq的调度策略
    Rabbitmq交换器Exchange和消息队列
    RabbitMQ概念
    微服务拆分
    微服务演化
    2018第44周日
    福勒(Martin Fowler)
    微服务架构定义那点事
  • 原文地址:https://www.cnblogs.com/coldchair/p/12694556.html
Copyright © 2011-2022 走看看