0
点赞
收藏
分享

微信扫一扫

【YBTOJ进阶训练指导】二叉查找树【RMQ】【dfs】【ST表】

他说Python 2022-03-11 阅读 83

在这里插入图片描述

把数组排序,那么其中连续的一段一定是树里边一颗子树
那么我们把那一段最先插入的点找出来最为子树的根,然后分成两颗树继续往下递归
具体查最先插入方法用ST表就可以了

c o d e code code

#include<iostream>
#include<cstdio>
#include<algorithm> 
#include<cmath>

using namespace std;

long long n;
long long dep[301000], f[301010][32], b[301010];
struct node
{
	long long x, id;
}a[301010];

bool cmp(node x, node y)
{
	return x.x<y.x;
}

void dfs(long long l, long long r, long long d)
{
	if(l>r)
		return;
	long long k=log2(r-l+1);
	long long x=min(f[l][k], f[r-(1<<k)+1][k]); 
	dep[x]=d;
	dfs(l, b[x]-1, d+1);
	dfs(b[x]+1, r, d+1);
}

int main()
{
	scanf("%lld", &n);
	for(long long i=1; i<=n; i++)
		scanf("%lld", &a[i].x), a[i].id=i;
	sort(a+1, a+1+n, cmp);
	for(long long i=1; i<=n; i++)
		f[i][0]=a[i].id, b[a[i].id]=i;
	for(long long j=1; j<=log2(n); j++)
		for(long long i=1; i+(1<<j)-1<=n; i++)
			f[i][j]=min(f[i][j-1], f[i+(1<<j-1)][j-1]);
	dfs(1, n, 0);
	long long sum=0;
	for(long long i=1; i<=n; i++)
	{
		sum+=dep[i];
		printf("%lld\n", sum);
	}
	return 0;
}
举报

相关推荐

0 条评论