S - Query on a tree HDU - 3804 segment tree

 Topic effect: to give you a tree, so that you find this tree asked to point directly to the root node is less than the maximum equal to the length of val.

Before writing this topic and that you give this tree a tree to ask the right node to node between the root weight of less than or equal to multiplying the number k very much like.

Prior is not that into them pop operation, this is the same, before using a discrete idea to seek to reverse this start did not expect.

Then wrote out a very violent tree line, tree line if it is not a continuous interval is a high complexity.

So find a way to convert this into a continuous range, the same as above by reverse order of thinking can also be converted into a continuous range.

First, put the number of discrete and achievements, it is the last sequence + dfs tree line.

I wrote to note initialization, because it may be asked at the time of the root node 1, this will not be taken into account in the back, so the output of the array to be initialized to -1

Then I was out of a query in here, id << 1, forget the | 1,

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <vector>
#include <math.h>
#include <iostream>
#include <algorithm>
#define debug(n) printf("%d\n",n)
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 100;
int n, out[maxn], b[maxn], len;
struct node {
    int v;
    int w;
    node(int v = 0, int w = 0) :v(v), w(w) {}
};
struct edge {
    int w;
    int id;
    edge(int w = 0, int id = 0) :w(w), id(id) {}
};
vector<node>G[maxn];
vector<edge>e[maxn];
int sum[maxn * 4], maxx[maxn * 4];

void push_up(int id) {
    sum[id] = sum[id << 1] + sum[id << 1 | 1];
    maxx[id] = max(maxx[id << 1], maxx[id << 1 | 1]);
    // printf("maxx[%d]=%d\n",id,maxx[id]);
}

void update(int id, int l, int r, int pos, int val) {
    // printf("id=%d l=%d r=%d pos=%d val=%d\n", id, l, r, pos, val);
    if (l == r) {
        sum[id] += val;
        if (sum[id]) maxx[id] = l;
        else maxx[id] = 0;
        return;
    }
    int mid = (l + r) >> 1;
    if (pos <= mid) update(id << 1, l, mid, pos, val);
    else update(id << 1 | 1, mid + 1, r, pos, val);
    push_up(id);
}

int query(int id, int l, int r, int x, int y) {
    if (x <= l && y >= r) return maxx[id];
    int mid = (l + r) >> 1;
    int ans = 0;
    // printf("id=%d x=%d y=%d\n",id,x,y);
    if (x <= mid) ans = max(ans, query(id << 1, l, mid, x, y));
    // cout<<x<<' '<<y<<endl;
    if (y > mid) ans = max(ans, query(id << 1 | 1, mid + 1, r, x, y));
    // printf("!!id=%d ans=%d x=%intd y=%intd mid=%d\n", id, ans,x,y,mid);

    return ans;
}

void dfs(int u, int pre) {
    for (int i = 0; i < G[u].size(); i++) {
        node now = G[u][i];
        if (now.v == pre) continue;
        int t = lower_bound(b + 1, b + 1 + len, now.w) - b;
        update(1, 1, len, t, 1);
        // printf("www now.v=%d t=%d\n",now.v,t);
        for (int j = 0; j < e[now.v].size(); j++) {
            edge x = e[now.v][j];
            int t1 = upper_bound(b + 1, b + 1 + len, x.w) - b - 1;
            int ans = 0;
            if (t1 <= 0) {
                //  cout<<x.id<<'!'<<endl;
                out[x.id] = -1;
            }
            else {
                // printf("t1=%d\n",t1);
                ans = query(1, 1, len, 1, t1);
                if (ans == 0) out[x.id] = -1;
                else out[x.id] = b[ans];
            }
        }
        dfs(now.v, u);
        update(1, 1, len, t, -1);
        // printf("qqq now.v=%d t=%d\n",now.v,t);
    }
}


int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        scanf("%d", &n);
        for (int i = 0; i <= n; i++) G[i].clear(), e[i].clear();
        for (int i = 1; i < n; i++) {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            G[u].push_back(node(v, w));
            G[v].push_back(node(u, w));
            b[i] = w;
        }
        sort(b + 1, b + n);
        len = unique(b + 1, b + n) - b - 1;
        memset(sum, 0, sizeof(sum));
        memset(maxx, 0, sizeof(maxx));
        int q;
        scanf("%d", &q);
        for (int i = 1; i <= q; i++) {
            int u, w;
            scanf("%d%d", &u, &w);
            e[u].push_back(edge(w, i));
        }
        memset(out, -1, sizeof(out));
        dfs(1, -1);
        for (int i = 1; i <= q; i++) printf("%d\n", out[i]);
    }
    return 0;
}
/*
 4
 5
1 2 2
1 3 4
2 4 6
2 5 8
2
3 4
2 2
 */
+ Dfs sequence segment tree

 

Guess you like

Origin www.cnblogs.com/EchoZQN/p/11263634.html