2021.07.13【NOIP提高B组】模拟 JIH的玩偶

这篇博客主要介绍了如何使用倍增算法来高效地处理区间最大值和最小值的查询。作者首先阐述了思路,即通过维护max和min数组以及答案数组ans,然后进行层次遍历来更新信息。代码中展示了C++实现的细节,包括读取数据、初始化、层次更新以及查询操作。这个算法对于处理动态查询场景非常有用。
摘要由CSDN通过智能技术生成

在这里插入图片描述

思路:

很容易想到倍增,维护一个max和min还有ans,之后统计就行了

c o d e code code

#include<iostream>
#include<cstdio>

using namespace std;

int n, f[200100][40], maxx[200100][40], minn[200100][40], ans[200100][40];
int a[1001010];

int main()
{
	freopen("tree.in", "r", stdin);
	freopen("tree.out", "w", stdout);
	scanf("%d", &n);
	minn[0][0]=1e9;
	for(int i=1; i<=n; i++)
	{
		scanf("%d", &a[i]);
		maxx[i][0]=a[i];
		minn[i][0]=a[i];
	}
	for(int i=1; i<n; i++)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		f[x][0]=y;
	}
	for(int j=1; j<=18; j++)
		for(int i=1; i<=n; i++)
		{
			f[i][j]=f[f[i][j-1]][j-1];
			int k=f[i][j-1];
			maxx[i][j]=max(maxx[i][j-1], maxx[k][j-1]);
			minn[i][j]=min(minn[i][j-1], minn[k][j-1]);
			ans[i][j]=max(0, max(maxx[k][j-1]-minn[i][j-1], max(ans[i][j-1], ans[k][j-1])));
		}
	int q;
	scanf("%d", &q);
	while(q--)
	{
		int x, k;
		scanf("%d%d", &x, &k);
		int ans1=0, minn1=1e9;
		for(int j=0; k; j++, k>>=1)
		{
			if(k&1)
			{
				ans1=max(ans1, max(ans[x][j], maxx[x][j]-minn1));
				minn1=min(minn1, minn[x][j]);
				x=f[x][j];
			}
		}
		printf("%d\n", ans1);
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值