其他分享
首页 > 其他分享> > 陶陶摘苹果「线段树维护单调栈」

陶陶摘苹果「线段树维护单调栈」

作者:互联网

题目描述

题库后缀为contest/132/problem/2

思路分析

关于线段树维护单调栈

\(Code\)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define R register
#define N 100010
using namespace std;
inline int read(){
	int x = 0,f = 1;
	char ch = getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
int n,m,h[N];
struct node{
	int mx,len,l,r;//mx为区间最大值,len满足单调性的长度。
}tr[N<<2];
#define ls rt<<1
#define rs rt<<1|1
int calc(int rt,int w){
	if(tr[rt].l==tr[rt].r)return tr[rt].mx > w;//③
	if(tr[ls].mx>w)return calc(ls,w)+tr[rs].len;//①
	else return calc(rs,w);//②
}
void pushup(int rt){
	tr[rt].mx = max(tr[ls].mx,tr[rs].mx);
	tr[rs].len = calc(rs,tr[ls].mx);//左儿子和谐右儿子
}
void build(int rt,int l,int r){
	tr[rt].l = l,tr[rt].r = r;
	if(l==r)return tr[rt].mx = h[l],void();
	int mid = (l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	pushup(rt);
}
void modify(int rt,int x){
	if(tr[rt].l==tr[rt].r)return tr[rt].mx = h[tr[rt].l],void();
	int mid = (tr[rt].l+tr[rt].r)>>1;
	if(x<=mid)modify(ls,x);
	else modify(rs,x);
	pushup(rt);
}
int main(){
#if 1
	freopen("taopapp.in","r",stdin);
	freopen("taopapp.out","w",stdout);
#endif
	n = read(),m = read();
	for(R int i = 1;i <= n;i++)h[i] = read();
	build(1,1,n);
	for(R int i = 1;i <= m;i++){
		int pos = read(),height = read();
		int pre = h[pos];
		h[pos] = height;
		modify(1,pos);
		printf("%d\n",calc(1,-1));
		h[pos] = pre;
		modify(1,pos);
	}
	return 0;
}

标签:rt,rs,int,线段,tr,儿子,陶陶,mx,单调
来源: https://www.cnblogs.com/hhhhalo/p/13800824.html