zoukankan      html  css  js  c++  java
  • 2566

    #include<cstdio>
    #include<cstring>
    #include<set>
    #include<algorithm>
    #include<vector>
    
    using namespace std;
    
    const int MAX_SIZE = 12000;
    const int INF = 0x3f3f3f3f;
    
    struct Node{
        int l, r;
        Node *left, *right;
        int minn, tag;
    };
    
    Node tree[MAX_SIZE * 2 + 10]; int tn;
    
    inline void update(Node* cur, int v){
        if(cur -> tag > v){
        cur -> tag = v;
        cur -> minn = min(cur -> minn, v);
        }
    }
    
    inline void pushDown(Node* cur){
        if(cur -> tag != INF){
        if(cur -> l != cur -> r){
            update(cur -> left, cur -> tag);
            update(cur -> right, cur -> tag);
        }
        cur -> tag = INF;
        }
    }
    
    Node* build(int l, int r){
        Node* cur = tree + (tn ++);
        cur -> l = l;
        cur -> r = r;
        cur -> minn = cur -> tag = INF;
        if(l != r){
        int mid = (l + r) >> 1;
        cur -> left = build(l, mid);
        cur -> right = build(mid + 1, r);
        }
        return cur;
    }
    
    Node* sroot;
    
    struct O{
        int id, co;
    };
    
    vector<int> event[MAX_SIZE + 10];
    multiset<int> s[MAX_SIZE * 2 + 10];
    int val[MAX_SIZE * 2 + 10], vn;
    int data[MAX_SIZE + 10], n;
    int nodes[MAX_SIZE + 10], nxt[MAX_SIZE * 2 + 10], to[MAX_SIZE * 2 + 10], en;
    int len[MAX_SIZE * 2 + 10];
    int m;
    bool vis[MAX_SIZE + 10];
    int root, minn, tot, size[MAX_SIZE + 10];
    O cg[MAX_SIZE + 10];
    int dist[MAX_SIZE + 10], clist[MAX_SIZE + 10], cn;
    int cco[MAX_SIZE + 10];
    int pre[MAX_SIZE * 2 + 10], tVal[MAX_SIZE * 2 + 10];
    
    inline void addEdge(int f, int t, int w){
        ++ en;
        to[en] = t;
        len[en] = w;
        nxt[en] = nodes[f];
        nodes[f] = en;
    }
    
    void dfs(int cur, int fa){
        size[cur] = 1;
        for(int e = nodes[cur]; e; e = nxt[e]){
        if(to[e] == fa || vis[to[e]])
            continue;
        dfs(to[e], cur);
        size[cur] += size[to[e]];
        }
    }
    
    void findRoot(int cur, int fa){
        int maxn = tot - size[cur];
        for(int e = nodes[cur]; e; e = nxt[e]){
        if(to[e] == fa || vis[to[e]])
            continue;
        if(size[to[e]] > maxn)
            maxn = size[to[e]];
        findRoot(to[e], cur);
        }
        if(maxn < minn){
        minn = maxn;
        root = cur;
        }
    }
    
    void dfsDist(int cur, int fa){
        int si = (int)event[cur].size();
        for(int i = 0; i < si; i ++)
        clist[++ cn] = event[cur][i];
        cco[cur] = data[cur];
        int p = lower_bound(val, val + vn, data[cur]) - val;
        s[p].insert(dist[cur]);
        if((int)s[p].size() > 1){
        set<int>::iterator it = s[p].begin();
        int d = *it;
        ++ it;
        d += *it;
        if(tVal[p] > d)
            tVal[p] = d;
        }
        for(int e = nodes[cur]; e; e = nxt[e]){
        if(to[e] == fa || vis[to[e]])
            continue;
        dist[to[e]] = dist[cur] + len[e];
        dfsDist(to[e], cur);
        }
    }
    
    void change(Node* cur, int l, int r, int v){
        if(cur -> l == l && cur -> r == r){
        update(cur, v);
        return;
        }
        pushDown(cur);
        int mid = (cur -> l + cur -> r) >> 1;
        if(r <= mid)
        change(cur -> left, l, r, v);
        else if(l > mid)
        change(cur -> right, l, r, v);
        else{
        change(cur -> left, l, mid, v);
        change(cur -> right, mid + 1, r, v);
        }
        cur -> minn = min(cur -> left -> minn, cur -> right -> minn);
    }
    
    void clear(int cur, int fa){
        int p = lower_bound(val, val + vn, cco[cur]) - val;
        s[p].clear();
        p = lower_bound(val, val + vn, data[cur]) - val;
        change(sroot, pre[p], m, tVal[p]);
        pre[p] = 0; tVal[p] = INF;
        for(int e = nodes[cur]; e; e = nxt[e]){
        if(to[e] == fa || vis[to[e]])
            continue;
        clear(to[e], cur);
        }
    }
    
    void work(int cur){
        dfs(cur, 0);
        tot = size[cur];
        minn = INF;
        findRoot(cur, 0);
        cur = root;
        dist[cur] = 0;
        cn = 0;
        dfsDist(cur, 0);
        sort(clist + 1, clist + cn + 1);
        for(int i = 1; i <= cn; i ++){
        int t = clist[i];
        int p;
        p = lower_bound(val, val + vn, cco[cg[t].id]) - val;
        s[p].erase(s[p].find(dist[cg[t].id]));
        int d;
        if((int)s[p].size() > 1){
            set<int>::iterator it = s[p].begin();
            d = *it;
            ++ it;
            d += *it;
        } else
            d = INF;
        if(pre[p] != t){
            change(sroot, pre[p], t - 1, tVal[p]);
            pre[p] = t;
            tVal[p] = d;
        } else
            tVal[p] = min(tVal[p], d);
        cco[cg[t].id] = cg[t].co;
        p = lower_bound(val, val + vn, cco[cg[t].id]) - val;
        s[p].insert(dist[cg[t].id]);
        if((int)s[p].size() > 1){
            set<int>::iterator it = s[p].begin();
            d = *it;
            ++ it;
            d += *it;
        } else
            d = INF;
        if(pre[p] != t){
            change(sroot, pre[p], t - 1, tVal[p]);
            pre[p] = t;
            tVal[p] = d;
        } else
            tVal[p] = min(tVal[p], d);
        }
        //   s[0].clear();
        for(int i = 1; i <= cn; i ++){
        int t = clist[i];
        int p = lower_bound(val, val + vn, cg[t].co) - val;
        change(sroot, pre[p], m, tVal[p]);
        pre[p] = 0;
        tVal[p] = INF;
        }
        clear(cur, 0);
        vis[cur] = true;
        for(int e = nodes[cur]; e; e = nxt[e]){
        if(!vis[to[e]])
            work(to[e]);
        }
    }
    
    void print(Node* cur){
        if(cur -> l == cur -> r){
        if(cur -> minn == INF)
            printf("-1
    ");
        else
            printf("%d
    ", cur -> minn);
        return;
        }
        pushDown(cur);
        print(cur -> left);
        print(cur -> right);
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("test.in", "r", stdin);
        freopen("test.out", "w", stdout);
    #endif
        scanf("%d", &n);
        for(int i = 1; i <= n; i ++){
        scanf("%d", data + i);
        val[vn ++] = data[i];
        }
        for(int i = 1; i < n; i ++){
        int a, b, w;
        scanf("%d%d%d", &a, &b, &w);
        addEdge(a, b, w);
        addEdge(b, a, w);
        }
        scanf("%d", &m);
        for(int i = 1; i <= m; i ++){
        scanf("%d%d", &cg[i].id, &cg[i].co);
        event[cg[i].id].push_back(i);
        val[vn ++] = cg[i].co;
        }
        sort(val, val + vn);
        vn = unique(val, val + vn) - val;
        sroot = build(0, m);
        memset(tVal, INF, sizeof(tVal));
        work(1);
        for(int i = 0; i < vn; i ++)
        s[0].insert(INF);
        memset(pre, INF, sizeof(pre));
        print(sroot);
    //    printf("%d
    ", pre[2]);
    
        return 0;
    }
    View Code
  • 相关阅读:
    Mac上的USB存储设备使用痕迹在新版操作系统有所变化
    Beware of the encrypted VM
    A barrier for Mobile Forensics
    Second Space could let suspect play two different roles easily
    Take advantage of Checkra1n to Jailbreak iDevice for App analysis
    Find out "Who" and "Where"
    Where is the clone one and how to extract it?
    Downgrade extraction on phones running Android 7/8/9
    高版本安卓手机的取证未来
    How to extract WeChat chat messages from a smartphone running Android 7.x or above
  • 原文地址:https://www.cnblogs.com/zhonghaoxi/p/4167861.html
Copyright © 2011-2022 走看看