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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 【STM32】STM32 CubeMx使用教程一–安装教程

    【STM32】STM32 CubeMx使用教程一–安装教程一、STM32CubeMX简介1、STM32CubeMX是ST意法半导体近几年来大力推荐的STM32芯片图形化配置工具,目的就是为了方便开发者,允许用户使用图形化向导生成C初始化代码,可以大大减轻开发工作,时间和费用,提高开发效率。STM32CubeMX几乎覆盖了STM32全系列芯片。在CubeMX上,通过傻瓜化的操作便能实现相关配置,最终能够生成C语言代码,支持…

    2022年4月28日
    54
  • emule最新服务器地址,emule更新服务器列表

    emule最新服务器地址,emule更新服务器列表《emule更新服务器列表》由会员分享,可在线阅读,更多相关《emule更新服务器列表(15页珍藏版)》请在人人文库网上搜索。1、emule是通过ED2K网络和KAD网络寻找、连接其他emule客户端的,所以服务器列表和KAD节点文件是emule的必需文件。有些新手由于下载官方原版emule压缩包或其他未集成这些必需文件的emule压缩包,从而出现“连接不上ED2K与KAD”问题。所以学会下载更新…

    2022年6月29日
    495
  • 设置eclipse代码自动补全功能

    设置eclipse代码自动补全功能1.选择Eclipse菜单条中的Windows菜单下的Preferences项2.在左侧找到“Java”->“Editor”->“ContentAssist”3.在右侧“AutoActivation”项目下找到“AutoactivationtriggersforJava:”(可以看到设置框中默认的只有“.”,这就是为什么默认只有点“.”可以触发自动补全…

    2022年5月31日
    54
  • 常用的Java工具,16个

    常用的Java工具,16个在Java中,工具类定义了一组公共方法,这篇文章将介绍Java中使用最频繁及最通用的Java工具类。以下工具类、方法按使用流行度排名,参考数据来源于Github上随机选取的5万个开源项目源码。一.org.apache.commons.io.IOUtilscloseQuietly:关闭一个IO流、socket、或者selector且不抛出异常,通常放在finally块toString:转换IO流、Uri、byte[]为Stringcopy:IO流数据复制,从输入流写到输出流中,最大支持2GB

    2022年7月7日
    30
  • 深度学习-目标检测评估指标P-R曲线、AP、mAP[通俗易懂]

    深度学习-目标检测评估指标P-R曲线、AP、mAP[通俗易懂]mAP评估

    2022年6月29日
    56
  • centos7安装方法_ad9安装及激活成功教程教程

    centos7安装方法_ad9安装及激活成功教程教程本文超详细的将CentOS7的安装过程做了详细的记录,从下载镜像文件到安装CentOS再到最后的配置,手把手教学,保证能够顺利的将CentOS安装好、配置好。

    2022年10月4日
    4

发表回复

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

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