Orz..跑得还挺快的#10

自从会树链剖分后LCA就没写过倍增了...

这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树

-------------------------------------------------------------------------

#include<bits/stdc++.h>
 
#define rep(i, n) for(int i = 0; i < n; i++)
#define clr(x, c) memset(x, c, sizeof(x))
#define M(l, r) (((l) + (r)) >> 1)
#define foreach(i, x) for(__typeof(x.begin()) i = x.begin(); i != x.end(); i++)
 
using namespace std;
 
const int maxn = 200009;
 
int w[maxn], n, N, id[maxn];
vector<int> G[maxn];
 
namespace LCA {
    int top[maxn], son[maxn], dep[maxn], size[maxn], fa[maxn], TOP;
    
    void dfs(int x) {
   size[x] = 1; son[x] = -1;
   foreach(it, G[x]) if(*it != fa[x]) {
   dep[*it] = dep[x] + 1; 
   fa[*it] = x;
   dfs(*it);
   size[x] += size[*it];
   if(!~son[x] || size[*it] > size[son[x]])
       son[x] = *it;
   }
    }
    void DFS(int x) {
top[x] = TOP;
if(~son[x]) DFS(son[x]);
foreach(it, G[x]) if(*it != son[x] && *it != fa[x])
    DFS(TOP = *it);
}
   
void init() {
dep[0] = 0; fa[0] = -1;
dfs(0); DFS(TOP = 0);
}
int LCA(int x, int y) {
for(; top[x] != top[y]; x = fa[top[x]])
if(dep[top[x]] < dep[top[y]]) swap(x, y);
return dep[x] < dep[y] ? x : y;
}
}
 
struct Node {
Node *l, *r;
int s;
} pool[maxn * 40], *pt = pool, *null, *root[maxn];
 
void init() {
null = pt++; null->s = 0;
null->l = null->r = null;
}
 
int v;
Node* modify(Node* t, int l, int r) {
Node* h = pt++;
h->s = t->s + 1;
if(r > l) {
int m = M(l, r);
if(v <= m) {
h->l = modify(t->l, l, m);
h->r = t->r;
} else {
h->l = t->l;
h->r = modify(t->r, m + 1, r);
}
}
return h;
}
 
void build(int x, int fa = -1, Node* p = null) {
v = w[x] + 1;
root[x] = modify(p, 1, N);
foreach(it, G[x]) if(*it != fa)
   build(*it, x, root[x]);
}
 
inline int read() {
char c = getchar();
int ans = 0, f = 1;
for(; !isdigit(c); c = getchar())
   if(c == '-') f = -1;
for(; isdigit(c); c = getchar()) 
   ans = ans * 10 + c - '0';
return ans * f;
}
 
int ans = 0;
void work(bool F) {
int x = (read()^ans) - 1, y = read() - 1, k = read(), lca = LCA::LCA(x, y);
Node *X = root[x], *Y = root[y], *A = root[lca], *P = lca ? root[LCA::fa[lca]] : null;
int L = 1, R = N;
while(L < R) {
int s = X->l->s + Y->l->s - A->l->s - P->l->s, m = M(L, R);
if(s >= k) {
X = X->l; Y = Y->l; A = A->l; P = P->l;
R = m;
} else {
X = X->r; Y = Y->r; A = A->r; P = P->r;
k -= s;
L = m + 1;
}
}
ans = id[L - 1];
printf("%d", ans);
if(F) putchar('\n');
}
 
int main() {
freopen("test.in", "r", stdin);
init();
n = read();
int m = read();
rep(i, n) {
id[i] = w[i] = read();
   G[i].clear();
}
sort(id, id + n);
N = unique(id, id + n) - id;
rep(i, n) w[i] = lower_bound(id, id + N, w[i]) - id;
rep(i, n - 1) {
int u = read() - 1, v = read() - 1;
G[u].push_back(v);
G[v].push_back(u);
}
LCA::init();
build(0);
while(m--) work(m);
return 0;
}

-------------------------------------------------------------------------

2588: Spoj 10628. Count on a tree

Time Limit: 12 Sec  Memory Limit: 128 MB
Submit: 2675  Solved: 606
[Submit][Status][Discuss]

Description

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

Input

第一行两个整数N,M。
第二行有N个整数,其中第i个整数表示点i的权值。
后面N-1行每行两个整数(x,y),表示点x到点y有一条边。
最后M行每行两个整数(u,v,k),表示一组询问。

Output

 
M行,表示每个询问的答案。

Sample Input

8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
0 5 2
10 5 3
11 5 4
110 8 2

Sample Output

2
8
9
105
7

HINT

HINT:

N,M<=100000

暴力自重。。。

Source

BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )的更多相关文章

  1. BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]

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

  2. bzoj 2588 Spoj 10628. Count on a tree(主席树)

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

  3. bzoj 2588: Spoj 10628. Count on a tree【主席树+倍增】

    算是板子,把值离散化,每个点到跟上做主席树,然后查询的时候主席树上用u+v-lca-fa[lca]的值二分 #include<iostream> #include<cstdio> ...

  4. BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树

    2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/J ...

  5. 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 ...

  6. Bzoj 2588 Spoj 10628. Count on a tree(树链剖分LCA+主席树)

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MB Description 给定一棵N个节点的树,每个点 ...

  7. 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 ...

  8. bzoj 2588 Spoj 10628. Count on a tree (可持久化线段树)

    Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 7669  Solved: 1894[Submi ...

  9. 主席树 || 可持久化线段树 || 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) ...

随机推荐

  1. poj 2187 Beauty Contest 最远点距

    /** 求出凸包枚举每个点的矩距离即可 因为凸包上的点可定不多.. 学习: 刚开始WA 了一次,,因为用int 存的, 一看discuss 里提供的数据,想起来,,应该是越界了.. 后来用longlo ...

  2. AseoZdpAseo.init(this, AseoZdpAseo.INSERT_TYPE);

    让以后的人知道吧,这就是一个广告包,相当于广告插件.

  3. (step5.1.3)hdu 1213( How Many Tables——1213)

    题目大意:输入两个整数n,m.分别表示点数.对点的操作的次数.在接下来的m行中,每行有两个整数a,b.表示a和b是好朋友.(不是好朋友的不能坐在同一个桌子上) .求需要多少张桌子 解题思路:并查集 1 ...

  4. leetcode先刷_Search in Rotated Sorted Array II

    上一页下一页,找到相同的旋转阵列的问题.假设数组元素一再怎么办呢?会发生什么? 我给大家举一个极端的例子.如果是这样的阵列中的元件.1,1,2,1,1,1,1,我们想看看这个数组2,刚开始A[midd ...

  5. ADS2008 安装方法详解及文件下载

    一.我的安装的过程及方法 正常安装的方法: 1.- Install the program. 2.- Copy "license.lic" into "C:\ADS200 ...

  6. C#学习之------委托

    1.向窗体中添加控件的最少步骤:                 窗体的句柄为this private System.Windows.Forms.Button button1;             ...

  7. 网络编程(UDP协议-聊天程序)

    网络编程中的UDP协议中聊天程序,发送端口,和接受端口. 发送端口(Send): <span style="font-size:18px;">package cn.it ...

  8. 利用CentOS系统IPtables防火墙添加网站IP白名单

    参考博文: 利用CentOS系统IPtables防火墙添加360网站卫士节点IP白名单 centos6.5添加白名单如下: 在防火墙 配置文件中加入白名单  ip -A INPUT -s 183.13 ...

  9. 多层TreeWidget可选实现

    http://download.csdn.net/detail/lingyunfuyu2/9117481

  10. 设计模式 ( 十三 ) 命令模式Command(对象行为型)

    设计模式 ( 十三 ) 命令模式Command(对象行为型) 1.概述         在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需 ...