专栏文章

题解:P10516 数据结构

P10516题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mio4c5lo
此快照首次捕获于
2025/12/02 13:09
3 个月前
此快照最后确认于
2025/12/02 13:09
3 个月前
查看原文

题意:

实现区间修改,单点加 valval,以及区间查询 sumsum

思路:

很明显,对于区间操作,我们选择线段树,具体记录数据如下:
CPP
struct segment{
	int l,r;
	//区间左右端点l,r
	int sum,minn;
    //区间和sum,区间最小值minn    
}t[N<<2];

  • 对于操作 1,我们要记录区间区间 min\min,通过与 kk 进行比较判断该区间是否进行修改(特判一下如果 valval 值为零就跳过,没必要进行无意的计算)。
  • 对于操作 2,只需要找到对应的位置进行修改。
  • 对于操作 3,计算统计好的区间 sumsum

Code

CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+5;
inline void read(int &a){
	char ch;int f=1,k=0;ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){k=k*10+ch-'0';ch=getchar();}
	a=k*f;
}

struct segment{
	int l,r;
	int sum,minn;
}t[N<<2];

int a[N],b[N],n,m;

void push_up(int p){
	t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
	t[p].minn=min(t[p<<1].minn,t[p<<1|1].minn);
}
//建树 
void build(int p,int l,int r){
	t[p].l=l,t[p].r=r;
	if(l==r){
		t[p].minn=a[l]*b[l];
		t[p].sum=a[l]+b[l];
		return ;
	}
	int mid=l+r >>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	push_up(p);
}
//op==1
void modify(int p,int l,int r,int k,int val){
	if(t[p].minn>k) return ;
	if(t[p].l==t[p].r){
		a[t[p].l]+=val,b[t[p].l]+=val;
		t[p].sum=a[t[p].l]+b[t[p].l];
		t[p].minn=a[t[p].l]*b[t[p].l];
		return ;
	}
	int mid=t[p].l+t[p].r>>1;
	if(l<=mid) modify(p<<1,l,r,k,val);
	if(r>=mid+1) modify(p<<1|1,l,r,k,val);
	push_up(p);
}

//op==2
void update(int p,int i,int x,int y){
	if(t[p].l==t[p].r){
		a[i]=x,b[i]=y;
		t[p].minn=x*y;
		t[p].sum=x+y;
		return ;
	}
	int mid=t[p].l+t[p].r>>1;
	if(i<=mid) update(p<<1,i,x,y);
	else if(i>=mid+1) update(p<<1|1,i,x,y);
	push_up(p);
}
//op==3
int query(int p,int l,int r){
	if(l<=t[p].l&&t[p].r<=r){
		return t[p].sum;
	}
	int mid=t[p].l+t[p].r>>1,res=0;
	if(l<=mid) res+=query(p<<1,l,r);
	if(r>=mid+1) res+=query(p<<1|1,l,r);
	return res;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	read(n),read(m);
	for(int i=1;i<=n;i++) read(a[i]);
	for(int i=1;i<=n;i++) read(b[i]);
	int op;
	build(1,1,n);
	while(m--){
		read(op);
		if(op==1){
			int l,r,k,t;
			read(l),read(r),read(k),read(t);
			if(!t) continue;
			modify(1,l,r,k,t);
		}
		else if(op==2){
			int i,x,y;
			read(i),read(x),read(y);
			update(1,i,x,y);
		}
		else if(op==3){
			int l,r;
			read(l),read(r);
			cout<<query(1,l,r)<<"\n";
		}
	} 
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...