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 ...
随机推荐
- NGUI研究之在Unity中使用贝塞尔曲线
鼎鼎大名的贝塞尔曲线相信大家都耳熟能详.这两天由于工作的原因须要将贝塞尔曲线加在project中.那么我迅速的研究了一下成果就分享给大家了哦.贝塞尔曲线的原理是由两个点构成的随意角度的曲线,这两个点一 ...
- C++设计模式--观察员
概要 在软件构建过程中.我们须要为某些对象建立一种"通知依赖关系" --一个对象(目标对象)的状态发生改变,全部的依赖对象(观察者对象)都将得到通知.假设这种依赖关系过于紧密,将使 ...
- POJ3050 Hopscotch 【DFS】
Hopscotch Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2113 Accepted: 1514 Descrip ...
- Java如何检查List<String> 里是否有想要的字符串?
List<String> test = new ArrayList<String>(); test.add("a"); test.add("b&q ...
- Cordova CLI源码分析(一)——简介
本系列文章分析基于node.js的命令行工具Cordova CLI,所以如果对node.js基础不是很了解,建议参考http://nodejs.gamesys.net/node-js提供的基础教程 文 ...
- 怎样在万网加入Lync Online SRV记录
万网已经支持SRV记录解析了,可是有好几个朋友问我怎么加入SRV记录(假设域名提供商不支持,能够通过DNSPOD来实现),过程例如以下 1:绑定域名至Office 365 略,请查看我的视频或者博客中 ...
- 开源企业IM-免费企业即时通讯-ENTBOOST V2014.183 Windows版本号正式宣布
ENTBOOST,VERSION 2014.183 Windows(点击下载)版本号公布.主要添加PC端P2P(点对点)文件传输功能:公布安卓Android手机clientAPP 1.0版本号.公布苹 ...
- 边记边学PHP-(十五)MySQL数据库基础操作2
四.使用可视化工具创建数据库 尽管使用命令行感觉更像我们程序猿,可是我还是比較喜欢使用workbench来创建数据库. 首先打开workbench , 一个比較友好的界面就打开了,哈哈.我还是比較喜欢 ...
- Hadoop-2.2.0中文文档—— MapReduce下一代- 可插入的 Shuffle 和 Sort
简单介绍 可插入的 shuffle 和 sort 功能,同意在shuffle 和 sort 逻辑中用可选择的实现类替换.这个情况的样例是:用一个不是HTTP的应用协议,如RDMA来 shuffle 从 ...
- MapReduce(十五): 从HDFS阅读本文的源代码分析
以Map任务读取文本数据为例: 1) LineRecordReader负责对文件切割的定位,以及对读取每一行内容的封装供用户Map任务使用.每次在定位在文件里不为0的位置时,多读取一行,由于前一个 ...