线段树 RMQ 求hack
  • 板块题目总版
  • 楼主HgSO4_QwQ
  • 当前回复1
  • 已保存回复1
  • 发布时间2021/12/7 17:54
  • 上次更新2023/11/3 22:43:59
查看原帖
线段树 RMQ 求hack
422110
HgSO4_QwQ楼主2021/12/7 17:54

RT 代码如下

#include<iostream>
using namespace std;

int a[100010];

struct node
{
	int l,r,mn,mark;// l 右儿子 r 左儿子 mn 区间最小值 mark 懒惰标记
}tree[400010];

void build(int p,int cl,int cr)
{
	tree[p].l=cl;
	tree[p].r=cr;
	int mid=(cl+cr)/2;
	if(cl==cr) {tree[p].mn=a[cl];return ;}
	build(2*p,cl,mid);
	build(2*p+1,mid+1,cr);
	tree[p].mn=min(tree[2*p].mn,tree[2*p+1].mn);
}

void pd(int p)// 把节点的懒惰标记传给儿子
{
	if(tree[p].mark)
	{
		tree[2*p].mn+=tree[p].mark;
		tree[2*p].mark=tree[p].mark;
		tree[2*p+1].mn+=tree[p].mark;
		tree[2*p+1].mark=tree[p].mark;
		tree[p].mark=0;
	}
}

int lrupdate(int p,int ql,int qr,int d)
{
	int mn=0;
	if((ql<=tree[p].l&&qr>=tree[p].r)||tree[p].l==tree[p].r) 
//	if((ql<=tree[p].l&&qr>=tree[p].r)) 
	{
		tree[p].mark+=d;
		tree[p].mn+=d;
		return tree[p].mn;
	}
	pd(p);
	int mid=(tree[p].l+tree[p].r)/2;
	if(ql<=mid) 
	{
		mn+=lrupdate(2*p,ql,qr,1);
	}
	if(qr>mid) 
	{
		mn+=lrupdate(2*p+1,ql,qr,1);
	}
	tree[p].mn=min(tree[2*p].mn,tree[2*p+1].mn);
	return mn;
}

int query(int p,int ql,int qr)
{
	int mn=0;
	if((ql<=tree[p].l&&qr>=tree[p].r)||tree[p].l==tree[p].r) return tree[p].mn;
	int mid=(tree[p].l+tree[p].r)/2;
	if(qr<=mid) 
	{
		pd(p);
		mn+=query(2*p,ql,qr);
	}
	else if(ql>mid) 
	{
		pd(p);
		mn+=query(2*p+1,ql,qr);
	}
	else 
	{
		pd(p);
		mn=min(query(2*p,ql,mid),query(2*p+1,mid+1,qr));
	}
	return mn;
}

int main()
{
	ios::sync_with_stdio(0);
	int n,q;
	cin>>n>>q;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,1,n);
	while(q--)
	{
		int op,l,r;
		cin>>op>>l>>r;
		if(op==2) // 查询
		{
			cout<<query(1,l,r)<<endl;
		}
		else if(op==1) // 区间+1
		{
			lrupdate(1,l,r,1);
		}
	}
	return 0;
}

一直0分 dalao们求助

2021/12/7 17:54
加载中...