线段树莫名写挂求助!
查看原帖
线段树莫名写挂求助!
895690
gghack_Nythix楼主2023/1/14 15:22

rt

#include <bits/stdc++.h>
#define wccc inline
#define lid (id << 1)
#define rid (id << 1 | 1)
#define int long long
//id >> 1 lid id >> 1 | 1 rid
using namespace std;
const int MAX = 1000000;
struct seg_tr{
	int l,r;
	int mx,sum;
	int lazy,lazy2;
}tr[MAX];
int a[MAX];
wccc void bulid_tr(int id,int l,int r){
	tr[id].l = l;
	tr[id].r = r;
	if(l == r){//放置到最后节点
		tr[id].sum = a[l];
		tr[id].mx = a[l];
		return;
	}
	int mid = (l + r) >> 1;
	bulid_tr(lid,l,mid);
	bulid_tr(rid,mid + 1,r);//递归搜索
	tr[id].sum = tr[lid].sum + tr[rid].sum;//和加上左右节点的和
	tr[id].mx = max(tr[lid].mx,tr[rid].mx);//max为左右节点的最大值
}
wccc void pushdown(int id)//下放标记
{
    if(tr[id].lazy && tr[id].l != tr[id].r) //如果下放到lazy不为0,并且不是叶子节点
    {
        tr[lid].lazy += tr[id].lazy; //左儿子lazy+父亲节点lazy
        tr[rid].lazy += tr[id].lazy; //右儿子lazy+父亲节点lazy                                   
        tr[lid].sum += tr[id].lazy * (tr[lid].r - tr[lid].l + 1);//左儿子的sum+父亲节点lazy*(左儿子的右节点-左儿子的左节点+1)(个数)
        tr[rid].sum += tr[id].lazy * (tr[rid].r - tr[rid].l + 1);//同上
        tr[id].lazy = 0;//父亲节点的lazy清空
    }
}
//测测测好难
wccc int query(int id,int l,int r)//查询
{
	pushdown(id);
	if(tr[id].l == l && tr[id].r == r){
		return tr[id].sum;
	}
	int mid = (tr[id].l + tr[id].r) >> 1;
	if(r <= mid){
		return query(lid,l,r);
	}
	if(l > mid){
		return query(rid,l,r);
	}
	return query(lid,l,mid) + query(rid,mid + 1,r);
}
wccc void add(int id, int l, int r, int val) //加
{
	tr[id].mx = max(tr[lid].mx,tr[rid].mx);//max为左右节点的最大值
	pushdown(id);
    if(l==tr[id].l && r==tr[id].r) //匹配到后
    {
        tr[id].lazy += val;//lazy累计
       	tr[id].sum+=(tr[id].r-tr[id].l+1)*val;
        return;
    }
    int mid = (tr[id].l + tr[id].r) >> 1;//中点
    if(r <= mid){
        add(lid, l, r, val);//左儿子
    }
  	else if(l>mid)add(rid,l,r,val);
	else {
		add(lid,l,mid,val);
		add(rid,mid+1,r,val);
	}
    tr[id].sum = tr[lid].sum + tr[rid].sum;//pushup  回溯之前更新每个点的信息
}
wccc int checkmax(int id,int l ,int r){
	if(l <= tr[id].l && tr[id].r <= r){//查询成功
		return tr[id].mx;
	}
	pushdown(id);
	int mid = (l + r) >> 1;
	int maxxx = -1145141919;
	if(l <= mid){
		maxxx = max(maxxx,checkmax(lid,l,r));
	}
	else if(r >= mid){
		maxxx = max(maxxx,checkmax(rid,l,r));
	}
	return maxxx;
}
signed main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; i++){
		cin >> a[i];
	}
	bulid_tr(1,1,n);
	for (int i = 1; i <= m; i++)
	{
		char ope;
		int x, y;
		cin >> ope >> x >> y;
		if (ope == 'Q')
		{
			cout << checkmax(1,x,y) << endl;
		}
		else
		{
			if(a[x] < y){
				add(1,x,x ,a[x] - y);
			}
		}
	}
}
2023/1/14 15:22
加载中...