这题是裸的主席树,每个节点建一棵主席树,再加个lca就可以了。

  历尽艰辛,终于A掉了这一题,这般艰辛也显示出了打代码的不熟练。

  错误:1、lca倍增的时候i和j写反了,RE了5次,实在要吸取教训

     2、主席树插入操作的时候,如果插入到的那个点(叶节点)原来有值,而没有加上,导致了WA

  以下是历尽艰辛的代码,还很长。

 

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <map> using namespace std; const int maxn = ;
int n, m, w[maxn];
int head[maxn], label;
struct Edge
{
int v, next;
Edge (int v = , int next = ):
v(v), next(next) {}
}e[maxn*];
int depth[maxn], f[maxn][], root[maxn], temp[maxn], s_num;
queue <int> q;
map <int, int> id;
struct Tree
{
int sum[maxn*], ls[maxn*], rs[maxn*], cnt;
Tree ()
{
sum[] = , cnt = ;
}
void PushUp(int rt)
{
sum[rt] = sum[ls[rt]]+sum[rs[rt]];
}
void insert(int las_rt, int rt, int l, int r, int p, int d)
{
if (l == r)
{
sum[rt] = sum[las_rt]+d;
return ;
}
int mid = (l+r)>>;
if (p <= mid)
{
ls[rt] = ++cnt, rs[rt] = rs[las_rt];
insert(ls[las_rt], ls[rt], l, mid, p, d);
}
else
{
ls[rt] = ls[las_rt], rs[rt] = ++cnt;
insert(rs[las_rt], rs[rt], mid+, r, p, d);
}
PushUp(rt);
}
int query(int u_rt, int v_rt, int lca_rt, int lca_pos, int l, int r, int k)
{
if (l == r)
return l;
int mid = (l+r)>>;
int s_l = sum[ls[u_rt]]+sum[ls[v_rt]]-*sum[ls[lca_rt]]+(lca_pos >= l && lca_pos <= mid);
if (k <= s_l)
return query(ls[u_rt], ls[v_rt], ls[lca_rt], lca_pos, l, mid, k);
else
return query(rs[u_rt], rs[v_rt], rs[lca_rt], lca_pos, mid+, r, k-s_l);
}
}T; void ins(int u, int v)
{
e[++label] = Edge(v, head[u]);
head[u] = label;
} void in()
{
scanf("%d %d", &n, &m);
for (int i = ; i <= n; ++i)
scanf("%d", &w[i]);
for (int i = ; i <= n; ++i)
head[i] = -;
label = -;
for (int i = ; i < n; ++i)
{
int u, v;
scanf("%d %d", &u, &v);
ins(u, v), ins(v, u);
}
} void Build_lca()
{
for (int i = ; i <= ; ++i)
for (int j = ; j <= n; ++j)
f[j][i] = -;
q.push();
depth[] = ;
f[][] = -;
while (!q.empty())
{
int u = q.front();
for (int i = head[u]; i != -; i = e[i].next)
{
int v = e[i].v;
if (v == f[u][])
continue ;
f[v][] = u;
depth[v] = depth[u]+;
q.push(v);
}
q.pop();
}
for (int i = ; i <= ; ++i)
for (int j = ; j <= n; ++j)
{
if (f[j][i-] == -)
continue ;
f[j][i] = f[f[j][i-]][i-];
}
} void Hash_a()
{
for (int i = ; i <= n; ++i)
temp[i] = w[i];
sort(temp+, temp+n+);
s_num = ;
for (int i = ; i <= n; ++i)
if (temp[i] != temp[i-] || i == )
{
temp[++s_num] = temp[i];
id[temp[i]] = s_num;
}
} void dfs(int u)
{
root[u] = ++T.cnt;
T.insert(u == ? : root[f[u][]], root[u], , s_num, id[w[u]], );
for (int i = head[u]; i != -; i = e[i].next)
{
int v = e[i].v;
if (v == f[u][])
continue ;
dfs(v);
}
} void Build_tree()
{
Hash_a();
dfs();/*
for (int i = 1; i <= n; ++i)
printf("%d %d\n", i, T.sum[root[i]]);*/
} void prepare()
{
Build_lca();
Build_tree();
} int lca(int u, int v)
{
if (depth[u] < depth[v])
swap(u, v);
for (int i = ; i >= ; --i)
{
if (f[u][i] == -)
continue ;
if (depth[f[u][i]] >= depth[v])
{
u = f[u][i];
if (depth[u] == depth[v])
break ;
}
}
if (u == v)
return u;
for (int i = ; i >= ; --i)
{
if (f[u][i] == -)
continue ;
if (f[u][i] != f[v][i])
{
u = f[u][i];
v = f[v][i];
}
}
return f[u][];
} void work()
{
prepare();
while (m --)
{
int u, v, k;
scanf("%d %d %d", &u, &v, &k);
int t = lca(u, v);
int pos = T.query(root[u], root[v], root[t], id[w[t]], , s_num, k);
printf("%d\n", temp[pos]);
}
} int main()
{
in();
work();
return ;
}

  

SPOJ 10628. SPOJ COT Count on a tree 可持久化线段树的更多相关文章

  1. BZOJ - 2588 Spoj 10628. Count on a tree (可持久化线段树+LCA/树链剖分)

    题目链接 第一种方法,dfs序上建可持久化线段树,然后询问的时候把两点之间的所有树链扒出来做差. #include<bits/stdc++.h> using namespace std; ...

  2. SPOJ COT Count on a tree(树上主席树 + LCA 求点第k小)题解

    题意:n个点的树,每个点有权值,问你u~v路径第k小的点的权值是? 思路: 树上主席树就是每个点建一棵权值线段树,具体看JQ博客,LCA用倍增logn求出,具体原理看这里 树上主席树我每个点的存的是点 ...

  3. SPOJ 10628 COT - Count on a tree(在树上建立主席树)(LCA)

    COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to ...

  4. SPOJ - COT Count on a tree

    地址:http://www.spoj.com/problems/COT/en/ 题目: COT - Count on a tree #tree You are given a tree with N  ...

  5. 主席树 || 可持久化线段树 || LCA || BZOJ 2588: Spoj 10628. Count on a tree || Luogu P2633 Count on a tree

    题面: Count on a tree 题解: 主席树维护每个节点到根节点的权值出现次数,大体和主席树典型做法差不多,对于询问(X,Y),答案要计算ans(X)+ans(Y)-ans(LCA(X,Y) ...

  6. BZOJ 2588: Spoj 10628. Count on a tree-可持久化线段树+LCA(点权)(树上的操作) 无语(为什么我的LCA的板子不对)

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 9280  Solved: 2421 ...

  7. 主席树[可持久化线段树](hdu 2665 Kth number、SP 10628 Count on a tree、ZOJ 2112 Dynamic Rankings、codeforces 813E Army Creation、codeforces960F:Pathwalks )

    在今天三黑(恶意评分刷上去的那种)两紫的智推中,突然出现了P3834 [模板]可持久化线段树 1(主席树)就突然有了不详的预感2333 果然...然后我gg了!被大佬虐了! hdu 2665 Kth ...

  8. 「SP10628 COT - Count on a tree」

    主席树的综合运用题. 前置芝士 可持久化线段树:其实就是主席树了. LCA:最近公共祖先,本题需要在\(\log_2N\)及以内的时间复杂度内解决这个问题. 具体做法 主席树维护每个点到根节点这一条链 ...

  9. SPOJ Meteors - 可持久化线段树 - 二分法

    Byteotian Interstellar Union (BIU) has recently discovered a new planet in a nearby galaxy. The plan ...

随机推荐

  1. JS设计模式——4.继承(概念)

    类式继承 0.构造函数 一个简单的Person类 function Person(name){ this.name = name; } Person.prototype.getName = funct ...

  2. 消息队列ActiveMQ的使用详解

    通过上一篇文章 <消息队列深入解析>,我们已经消息队列是什么.使用消息队列的好处以及常见消息队列的简单介绍. 这一篇文章,主要带大家详细了解一下消息队列ActiveMQ的使用. 学习消息队 ...

  3. 我的Apache又挂了之apache错误:server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName'

    表示物理机装Apache然后有时候关机会忘了关闭Apache然后长此以往会导致各种Apache起不来的缘故,上一次已经出现过一次.今天又出现了 再次记录一下解决的方法. 1.查看错误日志 /var/l ...

  4. ProxySQL 监控和统计

    ProxySQL 监控和统计 很多有价值的统计数据在stats和monitor库中. admin@127.0.0.1 [(none)]>SHOW TABLES FROM stats; +---- ...

  5. ECMAScript 6 Promise 对象

    一.Promise的含义 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise是一个对象,从它可以获取异步操作的消息. 1. ...

  6. php+mysql缓存技术的实现

    本教程适合于那些对缓存SQL查询以减少数据库连接与执行的负载.提高脚本性能感兴趣的PHP程序员.概述 许多站点使用数据库作为站点数据存储的容器.数据库包含了产器信息.目录结构.文章或者留言本,有些数据 ...

  7. appium--【Mac】提示报错“could not launch WebDriverAgentRunner..........."

    运行appium   WebDriverAgentLib和WebDriverAgentRunner都编译到真机运行成功,未在桌面生成一个没图标的WebDriverAgentRunner 连接并选择自己 ...

  8. jquery datatable的详细用法

    1,首先需要引用下面两个文件 <link rel="stylesheet" href="https://cdn.datatables.net/1.10.16/css ...

  9. [实战]MVC5+EF6+MySql企业网盘实战(14)——逻辑重构

    写在前面 上篇文章关于修改文件夹和文件名称导致的找不到物理文件的问题,这篇文章将对其进行逻辑的修改. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6 ...

  10. LoadRunner中常用的字符串操作函数

    LoadRunner中常用的字符串操作函数有:                strcpy(destination_string, source_string);               strc ...