• 记录一种从天而降的掌法(动态维护中位数的方法)


    使用两个multiset,使得前一个里面存放最小的一半,后一个里面存放最大的一半。每次插入先插入到前一个里面。如果大于后一个的最小,移动即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    multiset<int> S,T; // Always S.size()==T.size() or S.size()==T.size()+1
    void eval(){
        if(S.size()){
            auto itr = S.end(); itr--;
            T.insert(*itr); S.erase(itr);
        }
        while(S.size() < T.size()){
            S.insert(*T.begin()); T.erase(T.begin());
        }
    }
    int val(){  // 获得中位数  
        auto itr = S.end(); itr--;
        if(S.size()==T.size()+1)return *itr;
        return (*itr+*T.begin())/2;
    }
    void erase(int x){
        auto itr = S.end(); itr--;
        if(*itr < x) T.erase(T.lower_bound(x));
        else S.erase(S.lower_bound(x));
    }
    
    int main(){
        int n; cin >> n;
        vector<int> A(n); for(int i = 0; i < n; i++) cin >> A[i];
        vector<int> dp(n);
        vector<vector<int>> g(n);
        for(int i = 0; i < n-1; i++){
            int a, b; cin >> a >> b; a--; b--;
            g[a].push_back(b); g[b].push_back(a);
        }
        function<void(int,int,int)> dfs=[&](int i,int p,int d){
            S.insert(A[i]); eval();
            int mi = 1000000005, ma = 0;
            for(int x : g[i]) if(x != p) {
                dfs(x, i, d+1);
                mi = min(mi,dp[x]); ma = max(ma,dp[x]);
            }
            if(ma == 0) dp[i] = val();
            else if(d&1) dp[i] = mi;
            else dp[i] = ma;
            erase(A[i]); eval();
        }; dfs(0,-1,0);
        cout << dp[0] << endl;
    }
    rush!
  • 相关阅读:
    Broadcom BCM94352z/DW1560驱动新姿势
    amd显卡更新最新驱动鼠标顿卡的解决方法
    设置 P2415Q & P2715Q 显示器使其支持 HDMI 2.0 启用 4k@60hz
    Web基础之Redis
    前端基础之AJAX
    Java基础之枚举
    解决Tomcat在idea控制台乱码问题
    JQuery基础
    JavaScript基础笔记
    前端基础之Html、CSS
  • 原文地址:https://www.cnblogs.com/LH2000/p/15273053.html
Copyright © 2020-2023  润新知