30help!!!
  • 板块P1531 I Hate It
  • 楼主hzy_Q
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/12/28 15:46
  • 上次更新2024/12/28 19:28:38
查看原帖
30help!!!
1112350
hzy_Q楼主2024/12/28 15:46
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+5;
int a[N];
struct node
{
	int l;//控制a的左端点
	int r;//控制a的右端点
	int val;//计算题目中要求的值 
}t[N*4];
//构造线段树 初始化t[]与a[]的映射关系
//bulid 1.t的id 2.a左端点 3.a右端点 
void build(int p,int L,int R)
{
	//0.初始化 初始当前节点p对应控制的a区间 
	t[p].l=L;t[p].r=R;//t[p]代表a[L,R] 
	//1.递归出口 当前节点为叶子 只有一个元素 
	if(L==R)
	{//区间值就应该是元素值 
		t[p].val=a[L];
		return;
	}
	//2.递归方程 分治算法 二分左右
	int mid=t[p].l+t[p].r>>1;//构造时也可以写成L+R>>1
	//只要节点p控制的元素数不为1一定存在子节点  递归构造左右子节点
	build(p<<1,L,mid);//构造左孩子
	build(p<<1|1,mid+1,R);//构造右孩子 p*2+1
	//pushup操作 计算出子节点的val后 计算当前节点的val
	t[p].val=max(t[p<<1].val,t[p<<1|1].val);
	return;
}
//修改 change/update(单点修改更改a[x]的值/区间修改[x,y]的值为k)
//单点修改 1.正在维护的t[]id 2.修改对应的a[]id
void change(int p,int x)
{
	//1.出口 如果当前t[]是个叶子 只有一个元素
	if(t[p].l==t[p].r)
	{
		//修改当前的值为新的a[]
		t[p].val=a[x];//这样写a[x]必须在主函数调用前提前维护好
		return; 
	}
	//2.方程 当前节点控制不止一个元素 一定有子节点 
	//找寻x在左或右子树上 二分查找逻辑
	int mid=t[p].l+t[p].r>>1;
	//在左子树上 修改左子树的值
	if(x<=mid) change(p<<1,x);
	//在右子树上 修改右子树的值
	if(x>mid) change(p<<1|1,x);
	//pushup操作 计算出子节点的val后 计算当前节点的val
	t[p].val=max(t[p<<1].val,t[p<<1|1].val);
	return;
}  
//查询 query(查询某区间的值)
//1.当前查询的t[]元素id 2.查询a[]区间左端点  3.查询a[]区间右端点
int query(int p,int L,int R)
{
	int maxx=-2e9;
	//1.出口 当前节点控制的区间刚好是查询区间
	if(t[p].l==L&&t[p].r==R)
	{//直接返回当前记录的值即可 
		return t[p].val;
	}
	//2.方程 查询区间是否落在左右孩子上
	int mid=t[p].l+t[p].r>>1;
	int ans=0;//用来计算区间和
	//查询目标区间一定与左孩子有交集满足:
	if(L<=mid) maxx=max(maxx,query(p<<1,L,min(mid,R)));
	//查询目标区间一定与右孩子有交集满足:
	if(R>mid) maxx=max(maxx,query(p<<1|1,max(mid+1,L),R));
	//返回最终求和的ans 
	return maxx; 
}
signed main()
{
	//定义输入信息 
	int n,m,x,y,k;
	char op;
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++) scanf("%lld",a+i);
	//1.初始化(构造树) 从根开始构造 控制的是[1,n] 
	build(1,1,n); 
	//2.模拟过程
	while(m--)
	{
		scanf(" %c",&op);
		//根据操作 执行不同逻辑
		if(op=='U')
		{
			//单点修改
			scanf("%lld%lld",&x,&k);
			if(a[x]<k) 
			{
				a[x]=y;
				change(1,x);
			}
		}
		else
		{
			//区间查询
			scanf("%lld%lld",&x,&y);
			printf("%lld\n",query(1,x,y));
		}
	}
	return 0;
}

ac会关注帮助我的大佬的!

2024/12/28 15:46
加载中...