PT07J - Query on a tree III DFS序 + 主席树

dfs序编号后跑权值主席树
但写起来是真的麻烦,总是wa,只能拿出模板过了

#include<bits/stdc++.h>
const int N = 100001;
using namespace std;

struct node {
    int to, ne;
} e[N<<1];

int n, m, len, l1, l2;
int id[N], rk[N], eid[N], re[N];
int he[N], a[N], b[N];
int val[N << 5], lc[N << 5], rc[N << 5], rt[N << 5];

void add(int x, int y) {
    e[++l2].to = y, e[l2].ne = he[x];
    he[x] = l2;
}

void dfs(int x, int fa) {
    id[x] = ++l1, rk[l1] = x;
    for(int i = he[x]; i; i = e[i].ne) {
        int y = e[i].to;
        if(y == fa) continue;
        dfs(y, x);
    }
    eid[x] = l1;
}

int change(int rt, int l, int r, int x, int y) {
    int now = ++len;
    lc[now] = lc[rt], rc[now] = rc[rt], val[now] = val[rt] + 1;
    if(l == r) {
        re[l] = y;
        return now;
    }
    int mid = (l + r) >> 1;
    if(x <= mid)
        lc[now] = change(lc[rt], l, mid, x, y);
    else
        rc[now] = change(rc[rt], mid + 1, r, x, y);
    return now;
}

int query(int u, int v, int l, int r, int k) {
    if(l == r)
        return re[l];
    int mid = (l + r) >> 1, s = val[lc[v]] - val[lc[u]], res;
    if(s >= k)
        res = query(lc[u], lc[v], l, mid, k);
    else
        res = query(rc[u], rc[v], mid + 1, r, k - s);
    return res;
}

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d", &a[i]), b[i] = a[i];
    sort(b + 1, b + n + 1);
    for( int i = 1; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        add(x, y);
        add(y, x);
    }
    dfs(1, 0);
    for(int i = 1; i <= n; i++) {
        a[rk[i]] = lower_bound(b + 1, b + n + 1, a[rk[i]]) - b;
        rt[i] = change(rt[i - 1], 1, n, a[rk[i]], rk[i]);
    }
    scanf("%d", &m);
    for(int i = 1; i <= m; i++) {
        int x, k;
        scanf("%d%d", &x, &k);
        printf("%d\n", query(rt[id[x] - 1], rt[eid[x]], 1, n, k));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/xxfy1/p/12263283.html

时间: 2024-07-29 08:59:21

PT07J - Query on a tree III DFS序 + 主席树的相关文章

【bzoj1803】Spoj1487 Query on a tree III DFS序+主席树

题目描述 You are given a node-labeled rooted tree with n nodes. Define the query (x, k): Find the node whose label is k-th largest in the subtree of the node x. Assume no two nodes have the same labels. 输入 The first line contains one integer n (1 <= n <

Codeforces 620E New Year Tree(DFS序+线段树)

题目大概说给一棵树,树上结点都有颜色(1到60),进行下面两个操作:把某结点为根的子树染成某一颜色.询问某结点为根的子树有多少种颜色. 子树,显然DFS序,把子树结点映射到连续的区间.而注意到颜色60种,这样就可以用一个64位整型去表示颜色的集合,然后就是在这个连续区间中用线段树成段更新颜色集合和区间查询颜色集合了. 1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 #define MAXN 500000

BZOJ 3439: Kpm的MC密码( trie + DFS序 + 主席树 )

把串倒过来插进trie上, 那么一个串的kpm串就是在以这个串最后一个为根的子树, 子树k大值的经典问题用dfs序+可持久化线段树就可以O(NlogN)解决 ------------------------------------------------------------------ #include<cstdio> #include<cstring> #include<algorithm> #include<cctype> using namespa

BZOJ 3011: [Usaco2012 Dec]Running Away From the Barn( dfs序 + 主席树 )

子树操作, dfs序即可.然后计算<=L就直接在可持久化线段树上查询 ------------------------------------------------------------------- #include<bits/stdc++.h> using namespace std; #define M(l, r) (((l) + (r)) >> 1) const int maxn = 200009; typedef long long ll; inline ll

CodeForces 547E:Mike and Friends(AC自动机+DFS序+主席树)

What-The-Fatherland is a strange country! All phone numbers there are strings consisting of lowercase English letters. What is double strange that a phone number can be associated with several bears! In that country there is a rock band called CF con

Codeforces 343D Water Tree(DFS序+线段树+技巧)

题目链接:http://codeforces.com/problemset/problem/343/D 题目: Mad scientist Mike has constructed a rooted tree, which consists of n vertices. Each vertex is a reservoir which can be either empty or filled with water. The vertices of the tree are numbered f

CodeForces 620E&quot;New Year Tree&quot;(DFS序+线段树)

传送门 •题意 给你一颗 n 个节点的树,每个节点被染上了颜色: 有 m 次操作,每次操作的类型有两种 1 v c : 将以 v 为根的子树的结点全部涂成 c 2 v : 询问以 v 为根的子树的结点中不同颜色的数量 •题解 原文地址:https://www.cnblogs.com/violet-acmer/p/11766465.html

bzoj4771 七彩树 dfs序+主席树+树链的并

题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4771 题解 一道不错的树链并的基础练习题. 如果不是树,而是一个数组的话,对于给定区间内的不同颜色数,我们可以维护一个 \(pre_{i, j}\) 表示前 \(i\) 个最后一个 \(j\) 出现的位置.那么答案就是 \(pre_{r, j} \geq l\) 的 \(j\) 的个数,用主席树维护,第一维 \(i\),第二维 \(pre_i, j\),维护的是数量就可以了.(当然这个问题还

BZOJ1803: Spoj1487 Query on a tree III

1803: Spoj1487 Query on a tree III Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 286  Solved: 125[Submit][Status] Description You are given a node-labeled rooted tree with n nodes. Define the query (x, k): Find the node whose label is k-th largest in