BZOJ 2588 Count on a tree (COT) 是持久的段树

BZOJ 2588 Count on a tree (COT) 是持久的段树

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

标题效果:两棵树之间的首次查询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);
}

版权声明:本文博客原创文章。博客,未经同意,不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/117451.html原文链接:https://javaforall.net

(0)
上一篇 2022年1月5日 下午5:00
下一篇 2022年1月5日 下午5:00


相关推荐

  • C封装继承多态

    C封装继承多态C 面向对象 封装 继承 多态 C 是一种面向对象语言 所以有面向对象的三大特征 封装 继承 多态简单来说 继承呢 就是减少代码的耦合性 也避免麻烦 所以一个类里面可以继承别的类的方法 属性 以及字段 多态呢 就是在继承的基础上 方法或者字段在父类或者子类里面相互引用 and 同名方法表现出的不同操作和功能 封装就是有些地方不想给别人看 就给代码加上访问权限 下面来详细讲一下 封装 一般情况下 我们在自己的代码里面用 private 比较多 主要是在当前类里面可以访问 保护代码的私密性 其次就是 publ

    2026年3月18日
    2
  • CSDN博文写作规范文档

    CSDN博文写作规范文档大家在 CSDN 写博客 一定有机会碰到 发文助手 给你的提示 提醒你注意 创作规范 了解规则 等等 这篇文章就是从 CSDN 平台运营的角度 谈谈怎么写一个好的 CSDN 技术博客 我们也在看用户的评论 不断提高我们的提示信息 让这些信息能更友好 更有效

    2026年3月19日
    1
  • tensorflow pycharm教程_tensorflow支持python3.8吗

    tensorflow pycharm教程_tensorflow支持python3.8吗pycharm使用tensorflow流程最近在学人工智能与大数据管理,环境是python+tensorflow。但配置有些麻烦,记录一下。其实主要分为两个部分,配置tnsorflow和在pycharm中使用tensorflow。首次尝试平常安装python包都是去pycharm的setting里面,在设置ProjectInterpreter中点小加号去装的,但这次却报了错。想来应该是有些…

    2022年8月25日
    6
  • matlab遗传算法实例求最短路径_遗传算法经典实例

    matlab遗传算法实例求最短路径_遗传算法经典实例Matlab遗传算法实例

    2025年11月4日
    3
  • ITIL V3与ITIL V2的价值差异[通俗易懂]

    ITIL V3与ITIL V2的价值差异[通俗易懂]之前有篇日志写了ITILv3的介绍。这里说一下v3和v2才差异 ITILV3自从2007年推出后,已经将近两年了,这两年时间足够令相关的研究者和爱好者能知晓这个名词。对于新的名词、概念或者技术推出后,往往会有三个时期存在较多的争论,最热闹的时候一般是刚推出或临近推出的时期,而后慢慢冷淡一段时间后,不少有机会深入这些新事物的人慢慢地又会有第二个阶段的争论,最后一个阶段常常是这个新事物真正

    2022年10月6日
    8
  • fcntl 函数「建议收藏」

    fcntl 函数「建议收藏」fcntl函数浅解Linux系统中使用man查看fcntl函数的原型为fcntl(intfd,intcmd,……/arg/);自己在使用时用到了fcntl(intfd,intcmd,longarg);F_SETFL:设置文件状态标志。将文件的状态标志设置为第三个参数arg的值(取整数值),其中O_RDONLY,O_WRONLY,O_RDWR,O_CREAT

    2025年7月17日
    7

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号