样例都过不去WA+RE求调
  • 板块P1531 I Hate It
  • 楼主shx2011
  • 当前回复0
  • 已保存回复0
  • 发布时间2025/1/20 13:23
  • 上次更新2025/1/20 15:39:25
查看原帖
样例都过不去WA+RE求调
1071426
shx2011楼主2025/1/20 13:23

rt

#include<bits/stdc++.h>
using namespace std;
typedef long long LL; //不开long long见祖宗 
const LL N=1e5+10;
LL tree[4*N],a[N],add[4*N],n; //节点数最多4N 
void build(LL l,LL r,LL k){//l:左端点 r:右端点 k:节点编号
    if(l==r){//如果是叶子节点(叶子节点的左右端点相等,即长度为1)
        tree[k]=a[l];//赋值
        return;
    }
    
    LL mid=(l+r)>>1;//取中间值,分割 
    build(l,mid,2*k);//拆分左子树
    build(mid+1,r,2*k+1);//拆分右子树
    tree[k]=max(tree[2*k],tree[2*k+1]);//pushup:回溯时利用子节点更新父节点(此处维护最大值)
}

void change(LL k,LL l,LL r,LL v){//修改一个节点 
	tree[k]+=v*(r-l+1);//修改值 
	add[k]+=v;//标记 
}

void down(LL k,LL l,LL r){//标记下放 
	if(add[k]!=0){
		LL mid=(l+r)>>1;
		change(k*2,l,mid,add[k]);//下放到左孩子 
		change(k*2+1,mid+1,r,add[k]);//下放到右孩子 
		add[k]=0;//父节点标记清空 
	}
}
void update(LL k,LL l,LL r,LL x,LL y,LL v){//把节点p的值改为x l:左端点 r:右端点 k:当前节点编号
    if(l>=x && r<=y){//如果无需继续递归就停止
    	change(k,l,r,v);//修改该节点的值 
    	return;
	}
	//如果区间没有完全包含在修改范围内(需要继续递归) 
	down(k,l,r);//标记下放给左右子树 
    LL mid=(l+r)>>1;//分割 
    if(x<=mid) update(2*k,l,mid,x,y,v);//左子树 
    if(y>mid) update(2*k+1,mid+1,r,x,y,v);//右子树 
    tree[k]=tree[2*k]+tree[2*k+1];//加和维护 
}

LL quary(LL k,LL l,LL r,LL x,LL y){//查询x到y的区间最大值
     if(l>=x && r<=y){//如果当前的区间完全包含在查询区间中时,不需要继续递归
        return tree[k];//直接返回答案 
     }
	 down(k,l,r); //要递归左右子树,所以下放标记 
     LL mid=(l+r)>>1;//分割 
     LL res=0;//记录和 
     if(x<=mid){//左区间有覆盖
        res=max(res,quary(2*k,l,mid,x,y));//递归左子树 
     }
     if(y>mid){//右区间有覆盖
        res=max(res,quary(2*k+1,mid+1,r,x,y));//递归右子树 
     }

     return res;//返回和 
}

LL m;
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,n,1);
	for(LL i=1;i<=m;i++){
		char t;
		cin>>t;
		if(t=='U'){
			LL x,y,k;
			cin>>x>>k;
			int v=quary(1,1,n,x,x);
			if(v<k) update(1,1,n,x,x,k-v);
			
		}else{
			LL x,y;
			cin>>x>>y;
			cout<<quary(1,1,n,x,y)<<endl;
		}
	}
	return 0;
}
2025/1/20 13:23
加载中...