模仿jiangly封装的线段树单点修改模板

https://codeforces.com/contest/2057/problem/D

#include<bits/stdc++.h>
using namespace std;
#define x first
#define y second
#define int long long
#define endl '\n'
const int N=1e6+10,mod=998244353,INF=1e16;

typedef pair<int,int> PII;

#define ls u<<1
#define rs u<<1|1
//单点修改线段树,初始化时需要逐个单点修改
template<class Info>
struct SegmentTree {
	vector<Info> tr;
	int n;
	SegmentTree(int n_){
		init(n_);
	}
	void init(int n_){
		n=n_;
		tr.resize(4*n+4);
		build(1,1,n);
	}
	void build(int u,int l,int r){
		tr[u]=Info();
		if(l==r) return ;
		int m=l+r>>1;
		build(ls,l,m),build(rs,m+1,r);
		pushup(u);
	}
	void pushup(int u){
		tr[u]=tr[ls]+tr[rs];
	}
	void Modify(int u,int l,int r,int x,const Info &v){
		if(r<x||l>x)return ; 
		if(l==r&&x==l){
			tr[u]=v;
			return ;
		}
		int m=l+r>>1;
		Modify(ls,l,m,x,v);Modify(rs,m+1,r,x,v);
    	pushup(u);
	}
	void modify(int x,const Info &v){
		Modify(1,1,n,x,v);
	}
	Info Query(int u,int l,int r,int x,int y){//x和y是询问范围 
		if(l>y||r<x) return Info();
		if(l>=x&&r<=y) return tr[u];
		int m=l+r>>1;
		return Query(ls,l,m,x,y)+Query(rs,m+1,r,x,y);
	}
	Info query(int l,int r){
		return Query(1,1,n,l,r);
	}
};

struct Info{
	int rmx,lmx,rmi,lmi,ans;
	Info():rmx(-INF),lmx(-INF),rmi(INF),lmi(INF),ans(0){}
	Info(int x,int i):rmx(x-i),lmi(x-i),rmi(x+i),lmx(x+i),ans(0){}
};

Info operator+(const Info &a,const Info &b){
	Info c;
	c.rmx=max(a.rmx,b.rmx);
	c.lmx=max(a.lmx,b.lmx);
	c.rmi=min(a.rmi,b.rmi);
	c.lmi=min(a.lmi,b.lmi);
	c.ans=max(max(a.ans,b.ans),max(b.rmx-a.lmi,a.lmx-b.rmi));
	return c;
}

void slove(){
	int n,q;
	cin>>n>>q;
	SegmentTree<Info> seg(n);
	for(int i=1;i<=n;i++){
		int a;
		cin>>a;
		seg.modify(i,Info(a,i));
	}
	cout<<seg.query(1,n).ans<<endl;
	for(int i=1;i<=q;i++){
		int p,x;
		cin>>p>>x;
		seg.modify(p,Info(x,p));
		cout<<seg.query(1,n).ans<<endl;
	}
}
/*
2 0
1 10
*/
signed main(){
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
	int T=1;
	cin>>T;
	while(T--) slove();
}
#define ls u<<1
#define rs u<<1|1
//单点修改线段树,初始化时需要逐个单点修改
template<class Info>
struct SegmentTree {
	vector<Info> tr;
	int n;
	SegmentTree(int n_){
		init(n_);
	}
	void init(int n_){
		n=n_;
		tr.resize(4*n+4);
		build(1,1,n);
	}
	void build(int u,int l,int r){
		tr[u]=Info();
		if(l==r) return ;
		int m=l+r>>1;
		build(ls,l,m),build(rs,m+1,r);
		pushup(u);
	}
	void pushup(int u){
		tr[u]=tr[ls]+tr[rs];
	}
	void Modify(int u,int l,int r,int x,const Info &v){
		if(r<x||l>x)return ; 
		if(l==r&&x==l){
			tr[u]=v;
			return ;
		}
		int m=l+r>>1;
		Modify(ls,l,m,x,v);Modify(rs,m+1,r,x,v);
    	pushup(u);
	}
	void modify(int x,const Info &v){
		Modify(1,1,n,x,v);
	}
	Info Query(int u,int l,int r,int x,int y){//x和y是询问范围 
		if(l>y||r<x) return Info();
		if(l>=x&&r<=y) return tr[u];
		int m=l+r>>1;
		return Query(ls,l,m,x,y)+Query(rs,m+1,r,x,y);
	}
	Info query(int l,int r){
		return Query(1,1,n,l,r);
	}
	
	//找到[ql,qr]内,第一个大于等于d的位置,具体要求具体修改
	int find_fist(int u,int l,int r,int ql,int qr,int d){ 
		if(l==ql&&r==qr){
			if(tr[u].mx<d) return -1;
			else {
				if(l==r) return l;
				int mid=l+r>>1;
				if(tr[ls].mx>=d) return find_fist(ls,l,mid,ql,mid,d);
				return find_fist(rs,mid+1,r,mid+1,qr,d);
			}
		}
		int mid=(l+r)/2;
		if(qr<=mid) return find_fist(ls,l,mid,ql,qr,d);//左边区间优先 
		else if(ql>mid) return find_fist(rs,mid+1,r,ql,qr,d);
		else {
			int pos=find_fist(ls,l,mid,ql,mid,d);//先找左边的 
			if(pos==-1) pos=find_fist(rs,mid+1,r,mid+1,qr,d);//左边没找到,递归一下右边的区间 
			return pos; 
		}
	}
	
	int find_first(int ql,int qr,int d){
		return find_first(1,1,n,ql,qr,d);
	}
	
	//找到[ql,qr]内,最后一个大于等于d的位置,具体要求具体修改
	int find_last(int u,int l,int r,int ql,int qr,int d){ 
		if(l==ql&&r==qr){
			if(tr[u].mx<d) return -1;
			else {
				if(l==r) return l;
				int mid=l+r>>1;
				if(tr[rs].mx>=d) return find_last(rs,mid+1,r,mid+1,qr,d);
				return find_last(ls,l,mid,ql,mid,d);
			}
		}
		int mid=(l+r)/2;
		if(qr<=mid) return find_last(ls,l,mid,ql,qr,d);//右边区间优先
		else if(ql>mid) return find_last(rs,mid+1,r,ql,qr,d);
		else {
			int pos=find_last(rs,mid+1,r,mid+1,qr,d);//先找右边的 
			if(pos==-1) pos=find_last(ls,l,mid,ql,mid,d);//右边没找到,递归一下左边的区间 
			return pos;
		}
	}
	
	int find_last(int ql,int qr,int d){
		return find_last(1,1,n,ql,qr,d);
	}
};

struct Info{
	int mx;
	Info():mx(-INF){}
	Info(int x):mx(x){}
};
posted @   MENDAXZ  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示