BZOJ 2588 Count on a tree (COT) 是持久的段树
标题效果:两棵树之间的首次查询k大点的权利。
思维:树木覆盖树,事实上,它是正常的树木覆盖了持久段树。
由于使用权值段树可以寻求区间k大,然后应用到持久段树思想,间隔可以做减法。详见代码。
CODE:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 100010
#define NIL (tree[0])
using namespace std; pair<int,int> src[MAX]; struct Complex{
Complex *son[2];
int cnt; Complex(Complex *_,Complex *__,int ___):cnt(___) {
son[0] = _;
son[1] = __;
}
Complex() {}
}*tree[MAX]; int points,asks;
int xx[MAX]; int head[MAX],total;
int next[MAX << 1],aim[MAX << 1]; int father[MAX][20],deep[MAX]; inline void Add(int x,int y);
void DFS(int x);
void SparseTable(); Complex *BuildTree(Complex *pos,int x,int y,int val);
int GetAns(Complex *l,Complex *r,Complex *f,Complex *p,int x,int y,int k);
int GetLCA(int x,int y);
int Ask(int x,int y,int k); int main()
{
cin >> points >> asks;
for(int i = 1;i <= points; ++i)
scanf("%d",&src[i].first),src[i].second = i;
sort(src + 1,src + points + 1);
for(int i = 1;i <= points; ++i)
xx[src[i].second] = i;
for(int x,y,i = 1;i < points; ++i) {
scanf("%d%d",&x,&y);
Add(x,y),Add(y,x);
}
NIL = new Complex(NULL,NULL,0);
NIL->son[0] = NIL->son[1] = NIL;
DFS(1);
SparseTable();
int now = 0;
for(int x,y,k,i = 1;i <= asks; ++i) {
scanf("%d%d%d",&x,&y,&k);
printf("%d",now = src[Ask(x ^ now,y,k)].first);
if(i != asks) puts("");
}
return 0;
} inline void Add(int x,int y)
{
next[++total] = head[x];
aim[total] = y;
head[x] = total;
} void DFS(int x)
{
deep[x] = deep[father[x][0]] + 1;
tree[x] = BuildTree(tree[father[x][0]],1,points,xx[x]);
for(int i = head[x];i;i = next[i]) {
if(aim[i] == father[x][0]) continue;
father[aim[i]][0] = x;
DFS(aim[i]);
}
} void SparseTable()
{
for(int j = 1;j <= 19; ++j)
for(int i = 1;i <= points; ++i)
father[i][j] = father[father[i][j - 1]][j - 1];
} int Ask(int x,int y,int k)
{
int lca = GetLCA(x,y);
return GetAns(tree[x],tree[y],tree[lca],tree[father[lca][0]],1,points,k);
} Complex *BuildTree(Complex *pos,int x,int y,int val)
{
int mid = (x + y) >> 1;
if(x == y) return new Complex(NIL,NIL,pos->cnt + 1);
if(val <= mid) return new Complex(BuildTree(pos->son[0],x,mid,val),pos->son[1],pos->cnt + 1);
return new Complex(pos->son[0],BuildTree(pos->son[1],mid + 1,y,val),pos->cnt + 1);
} int GetLCA(int x,int y)
{
if(deep[x] < deep[y]) swap(x,y);
for(int i = 19; ~i; --i)
if(deep[father[x][i]] >= deep[y])
x = father[x][i];
if(x == y) return x;
for(int i = 19; ~i; --i)
if(father[x][i] != father[y][i])
x = father[x][i],y = father[y][i];
return father[x][0];
} int GetAns(Complex *l,Complex *r,Complex *f,Complex *p,int x,int y,int k)
{
if(x == y) return x;
int mid = (x + y) >> 1;
int temp = l->son[0]->cnt + r->son[0]->cnt - f->son[0]->cnt - p->son[0]->cnt;
if(k <= temp) return GetAns(l->son[0],r->son[0],f->son[0],p->son[0],x,mid,k);
return GetAns(l->son[1],r->son[1],f->son[1],p->son[1],mid + 1,y,k - temp);
}
版权声明:本文博客原创文章。博客,未经同意,不得转载。
BZOJ 2588 Count on a tree (COT) 是持久的段树的更多相关文章
- bzoj 2588 Count on a tree 解题报告
Count on a tree 题目描述 给定一棵\(N\)个节点的树,每个点有一个权值,对于\(M\)个询问\((u,v,k)\),你需要回答\(u\) \(xor\) \(lastans\)和\( ...
- BZOJ.2588.Count on a tree(主席树 静态树上第k小)
题目链接 /* 序列上的主席树 某点是利用前一个点的根建树 同理 树上的主席树 某个节点可以利用其父节点(is unique)的根建树 排名可以利用树上前缀和求得: 对于(u,v),w=LCA(u,v ...
- bzoj 2588 Count on a tree
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...
- 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 ...
- SPOJ 10628 Count on a tree(Tarjan离线LCA+主席树求树上第K小)
COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to ...
- 2588: Count on a tree
敢问和zwt的树有何区别..改了读入直接交..四百个人A,三百多个PE..于是果断贡献几发PE.. http://ideone.com/9XCg3D
- 【BZOJ】【2588】COT(Count On a Tree)
可持久化线段树 maya……树么……转化成序列……所以就写了个树链剖分……然后每个点保存的是从它到根的可持久化线段树. 然后就像序列一样查询……注意是多个左端点和多个右端点,处理方法类似BZOJ 19 ...
- 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 ...
- 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 ...
随机推荐
- hadoop在实现kmeans算法——一个mapreduce实施
写mapreduce程序实现kmeans算法.我们的想法可能是 1. 次迭代后的质心 2. map里.计算每一个质心与样本之间的距离,得到与样本距离最短的质心,以这个质心作为key,样本作为value ...
- 【android自己定义控件】自己定义View属性
1.自己定义View的属性 2.在View的构造方法中获得我们自己定义的属性 3.重写onMesure 4.重写onDraw 3这个步骤不是必须,当然了大部分情况下还是须要重写的. 1.自己定义Vie ...
- dede 首页或列表页调用文章内容页body内容
在使用dede过程,有的朋友会调调出文章的列表的内容出来,怎么调呢?当然是用dede的传参的数据查询语句了,方法如下: {dede:arclist flag=h typeid=2 row=1 titl ...
- Allegro绘制PCB流程
单位换算 1mil = 0.0254 mm 1mm = 39.3701 mil 默认情况下我们更倾向于使用mil单位绘制PCB板. 1 新建工程,File --> New... --> [ ...
- Storm具体解释一、Storm 概述
一.Storm概述 Storm是一个分布式的.可靠的.零失误的流式数据处理系统. 它的工作就是委派各种组件分别独立的处理一些简单任务.在Storm集群中处理输入流的是Spout组件,而Spo ...
- Windows Phone开发(12):认识一下独具个性的磁贴
原文:Windows Phone开发(12):认识一下独具个性的磁贴 对"磁贴"的理解是一点也不抽象的,为什么呢?只要你愿意启动WP系统,无论你是在模拟器中还是在真机中,是的,桌面 ...
- PHP --字符串编码转换(自动识别原编码)
/** * 对数据进行编码转换 * @param array/string $data 数组 * @param string $output 转换后的编码 */ function array_icon ...
- Red Gate系列之八 SQL Connect 1.1.1.19 Edition 数据库连接及操作工具 完全破解+使用教程
原文:Red Gate系列之八 SQL Connect 1.1.1.19 Edition 数据库连接及操作工具 完全破解+使用教程 Red Gate系列之八 SQL Connect 1.1.1.19 ...
- Objective C (iOS) for Qt C++ Developers(iOS开发,Qt开发人员需要了解什么?)
Qt/C++开发人员眼中的Obj-C 对于我们第一次自己定义iOS应用来说,对于来自Qt/C++开发人员来说,我不得不学习Objective-C相关语法与知识 为了让读者可以更easy理解这 ...
- <a href='javascript:void(0)' onclick='my()'></a>