zoukankan      html  css  js  c++  java
  • [机房测试]数据恢复

    Description

    Solution

    容易想到一个贪心的思路,记得有个叫什么国王的游戏的题,大概就是考虑邻项作差。如果 (x) 在前面比 (y) 在前面更优的话,一定有

    [b_{x}(a_y+S)+b_yS > b_y(a_x+S)+b_xS ]

    化简可得

    [b_xa_y > b_ya_x ]

    所以最有的情况是按这个排序再依次取。如果扩展到树上的话,就可以用一个堆维护,每次取出最大的。

    但是这样实际上是错的,因为有依赖关系,即可能有一个点的 (frac{b}{a}) 很小,但它的儿子却很大。这和蓝书上一道染色的题是一个道理。一个性质是,当前所有节点权值最大的点一定会在其父亲被选取之后立即被选择。那么就可以根据这个倒序更新答案,每次把权值最大的点合并到它的父亲,同时计算贡献。可以用并查集维护。

    #include<stdio.h>
    #include<algorithm>
    #include<queue>
    using namespace std;
     
    typedef long long ll;
     
    inline int read(){
        int x=0,flag=1; char c=getchar();
        while(c<'0'||c>'9'){if(c=='-') flag=0;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
        return flag? x:-x;
    }
     
    const int N=3e5+7;
     
    ll a[N],b[N];
    int Fa[N],fa[N],sz[N];
     
    struct Node{
        int pos,sz; ll x,y;
        Node(int pos_=0,int sz_=0,ll x_=0,ll y_=0):
            pos(pos_),sz(sz_),x(x_),y(y_){}
        bool operator <(const Node &X) const{
            return y*X.x<X.y*x;
        }
    };
     
    int find(int x){
        if(x==fa[x]) return x;
        return fa[x]=find(fa[x]);
    }
     
    priority_queue<Node> Q;
     
    int main(){
        int n=read(); fa[1]=sz[1]=1;
        for(int i=2;i<=n;i++) Fa[i]=read();
        for(int i=1;i<=n;i++){
            a[i]=read(),b[i]=read();
            if(i!=1) Q.push(Node(i,sz[fa[i]=i]=1,a[i],b[i]));
        }
        ll ans=0;
        while(!Q.empty()){
            Node t=Q.top(); Q.pop(); int u=t.pos;
            if(t.sz!=sz[u]) continue;
            int x=find(Fa[u]),y=find(u);
            if(x==y) continue;
            ans+=a[y]*b[x];
            a[x]+=a[y],b[x]+=b[y];
            sz[x]+=sz[y],fa[y]=x;
            if(x!=1) Q.push(Node(x,sz[x],a[x],b[x]));
        }
        printf("%lld",ans);
    }
    
  • 相关阅读:
    Php扩展--protocolbuffers消息打包
    Php扩展--seasLog日志扩展安装
    PHP系统编程--03.PHP进程信号处理
    PHP系统编程--01.多进程与多线程
    PHP系统编程--02.PHP守护进程化
    linux shell 之if-------用if做判断
    Connection:Keep-alive
    Http报头Accept与Content-Type的区别
    json解析
    JSON-lib框架,转换JSON、XML不再困难
  • 原文地址:https://www.cnblogs.com/wwlwQWQ/p/15375965.html
Copyright © 2011-2022 走看看