一、题目

  

COT - Count on a tree

You are given a tree with N nodes. The tree nodes are numbered from 1 to N. Each node has an integer weight.

We will ask you to perform the following operation:

  • u v k : ask for the kth minimum weight on the path from node u to node v

Input

In the first line there are two integers N and M. (N, M <= 100000)

In the second line there are N integers. The ith integer denotes the weight of the ith node.

In the next N-1 lines, each line contains two integers u v, which describes an edge (u, v).

In the next M lines, each line contains three integers u v k, which means an operation asking for the kth minimum weight on the path from node u to node v.

Output

For each operation, print its result.

Example

Input:
8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 82 5 12 5 22 5 32 5 47 8 2 
Output:
2891057 

题目链接:http://www.spoj.com/problems/COT/二、思路  原理其实和一维线性表序列的一样。只不过这是在树上操作。  在一维线性表序列中,扫描序列中每一个离散化后的数字,每一次新建的权值线段树都是基于前一次的。而在树中,对每一个子节点的数字,新建的线段树都是基于父节点的线段树的。
***************************未完待续……  
***************************
 三、源代码
#pragma GCC optimize(2)
#pragma comment(linker, "/STACK:102400000, 102400000")
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define MAXN 111111
LL n, q, m;
/*************树部分*******************/
typedef struct {
    int to, next;
} Edge;
Edge tree[MAXN * ];
int head[MAXN], ecnt;

void add(int from, int to) {
    tree[ecnt].to = to;
    tree[ecnt].next = head[from];
    head[from] = ecnt++;
}
/*************树部分*******************/
/*************LCA部分*******************/
], depth[MAXN];
void dfs4lca(int r, int par, int d) {
    parent[r][] = par, depth[r] = d;
    ; i = tree[i].next) {
        int to = tree[i].to;
        if(to != par)
            dfs4lca(to, r, d + );
    }
}
void init4lca() {
    dfs4lca(, -, );
    ; k < ; ++k) {
        ; v <= n; ++v) {
            )
                parent[v][k + ] = -;
            else
                parent[v][k + ] = parent[parent[v][k]][k];
        }
    }
}
int lca(int a, int b) {
    if(depth[a] < depth[b])
        swap(a, b);
    ; i < ; ++i) {
        )
            a = parent[a][i];
    }
    if(a == b)
        return a;

    ; i >= ; --i) {
        if(parent[a][i] != parent[b][i]) {
            a = parent[a][i];
            b = parent[b][i];
        }
    }
    ];
}
/*************LCA部分*******************/
/*************主席树部分*******************/
struct {
    int lch, rch, cnt;
} nodes[MAXN * ];
int root[MAXN], ncnt;

, int r = m) {
    if(!nroot) {
        nroot = ++ncnt;
        nodes[nroot].cnt = nodes[proot].cnt + ;
    }
    if(l == r)
        return;
    ;
    if(val <= mid) {
        nodes[nroot].rch = nodes[proot].rch;
        update(nodes[nroot].lch, nodes[proot].lch, val, l, mid);
    } else {
        nodes[nroot].lch = nodes[proot].lch;
        update(nodes[nroot].rch, nodes[proot].rch, val, mid + , r);
    }
}
, int r = m) {
    if(l == r)
        return l;
    int cnt = nodes[nodes[uroot].lch].cnt + nodes[nodes[vroot].lch].cnt
              - nodes[nodes[lcaroot].lch].cnt - nodes[nodes[lcafroot].lch].cnt;
    ;
    if(k <= cnt)
        return query(nodes[uroot].lch, nodes[vroot].lch, nodes[lcaroot].lch, nodes[lcafroot].lch, k, l, mid);
    else
        , r);
}
/*************主席树部分*******************/
/*************离散化部分*******************/
LL weight[MAXN], buf[MAXN], mp[MAXN];
int nwt[MAXN];
void discrete() {
    memcpy(buf + , weight + , ]) * n);
    sort(buf + , buf + n + );
    m = unique(buf + , buf + n + ) - buf - ;
    ; i <= n; ++i) {
        nwt[i] = lower_bound(buf + , buf + m + , weight[i]) - buf;
        mp[nwt[i]] = weight[i];
    }
}
/*************离散化部分*******************/
template <class T> inline void read(T &x) {
    int t;
    bool flag = false;
    ')) ;
    if(t == '-')
        flag = true, t = getchar();
    x = t - ';
    ')
        x = x *  + t - ';
    if(flag)
        x = -x;
}

void init() {
    memset(head, -, sizeof(head));
    ecnt = ;
    //nodes = 0, root = 0, ncnt = 0;
}

void dfs4tree(int r, int par) {
    ; i = tree[i].next) {
        int to = tree[i].to;
        if(to != par) {
            update(root[to], root[r], nwt[to]);
            dfs4tree(to, r);
        }
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif // ONLINE_JUDGE
    init();
    LL a, b, u, v, k, wt, uvlca, ans;
    scanf("%lld%lld", &n, &q);
    ; i <= n; ++i) {
        read(weight[i]);
    }
    ; i < n; ++i) {
        read(a), read(b);
        add(a, b);
        add(b, a);
    }
    init4lca();
    discrete();

    add(, );//添加一条虚边。
    dfs4tree(, -);

    while(q--) {
        read(u), read(v), read(k);
        uvlca = LL(lca(u, v));
        ans = mp[query(root[u], root[v], root[uvlca], root[parent[uvlca][]], int(k))];
        printf("%lld\n", ans);
    }
    ;
}

 

SPOJ Count on a tree(主席树+LCA)的更多相关文章

  1. 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA

    [BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...

  2. BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca

    分析:树上第k小,然后我想说的是主席树并不局限于线性表 详细分析请看http://www.cnblogs.com/rausen/p/4006116.html,讲的很好, 然后因为这个熟悉了主席树,真是 ...

  3. spoj COT - Count on a tree(主席树 +lca,树上第K大)

    您将获得一个包含N个节点的树.树节点的编号从1到Ñ.每个节点都有一个整数权重. 我们会要求您执行以下操作: uvk:询问从节点u到节点v的路径上的第k个最小权重 输入 在第一行中有两个整数Ñ和中号.( ...

  4. [bzoj2588][count on a tree] (主席树+lca)

    Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...

  5. 洛谷P2633/bzoj2588 Count on a tree (主席树)

    洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...

  6. Bzoj 2588: Spoj 10628. Count on a tree 主席树,离散化,可持久,倍增LCA

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2588 2588: Spoj 10628. Count on a tree Time Limit ...

  7. spoj cot: Count on a tree 主席树

    10628. Count on a tree Problem code: COT You are given a tree with N nodes.The tree nodes are number ...

  8. 【BZOJ-2588】Count on a tree 主席树 + 倍增

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 3749  Solved: 873[ ...

  9. 洛谷P2633 Count on a tree(主席树上树)

    题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...

随机推荐

  1. [sql]java.sql.Types的具体对应值(jdbcType)

    public final static int BIT   =  -7; public final static int TINYINT  =  -6; public final static int ...

  2. Jmeter非GUI模式启动

    首先我们需要了解,GUI和非GUI模式启动Jmeter对测试的影响:Jmeter可视化界面及监听器展示结果需要消耗负载资源,从而导致,在大并发的情况下GUI方式会导致负载机资源紧张,对性能造成影响 e ...

  3. 2016 CCPC Hangzhou Onsite

    A:题意:n个格子排成一排,每个a[i],要求重排成k个,每个人数相同,合并两个和划分成两个(可以不等)都是花费为1,问最小花费 题解:从前往后贪心即可,由于哪个地方忘开ll,wa了,全改成ll就过了 ...

  4. HDU 4540 线性DP

    威威猫系列故事——打地鼠 Time Limit: 300/100 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total ...

  5. ablout unbuntu default mysql

    http://www.ghostchina.com/how-to-reset-mysqls-root-password/ http://blog.csdn.net/u010603691/article ...

  6. LTE空口协议——是空口3GPP协议 不是网络IP协议

    [LTE基础知识]LTE空口协议分析 from:https://www.mscbsc.com/viewnews-102038.html控制面协议 控制面协议结构如下图所示. PDCP在网络侧终止于eN ...

  7. socket中 emit和on的写法

    socket.emit('action');表示发送了一个action命令,命令是字符串的,在另一端接收时,可以这么写: socket.on('action',function(){...});soc ...

  8. 集成学习之Boosting —— Gradient Boosting原理

    集成学习之Boosting -- AdaBoost原理 集成学习之Boosting -- AdaBoost实现 集成学习之Boosting -- Gradient Boosting原理 集成学习之Bo ...

  9. Beta阶段第2周/共2周 Scrum立会报告+燃尽图 13

    作业要求[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2411] 版本控制:https://git.coding.net/liuyy08 ...

  10. MarkDown格式作业模板

    发布的随笔可复制下面的MarkDowm模板 注意事项 标题第XX次作业替换成相应的第一次作业.第二次作业...... 代码托管的链接一定要换成自己的项目 码云提交历史截图必须是自己每周的提交截图 #& ...