线段树求调(区间和,区修区查)
  • 板块灌水区
  • 楼主_Kevin_Kaslana_
  • 当前回复5
  • 已保存回复5
  • 发布时间2025/1/4 20:20
  • 上次更新2025/1/4 23:32:38
查看原帖
线段树求调(区间和,区修区查)
749194
_Kevin_Kaslana_楼主2025/1/4 20:20
#include<bits/stdc++.h>
#define ls (p<<1)
#define rs ((p<<1)|1)
#define mid ((l+r)>>1)
using namespace std;
const int N=1e6;
int n;
int a[N+5];
struct node{
    int l,r,ans;
    int tag=0;
}tree[4*N+5];
void build(int l,int r,int p)
{
    if(l==r)
    {
        tree[p].ans=a[l];
        tree[p].l=l;
        tree[p].r=r;
        return;
    }
    build(l,mid,ls);
    build(mid+1,r,rs);
    tree[p].ans=tree[ls].ans+tree[rs].ans;
}
void push_down(int p)
{
    tree[ls].tag+=tree[p].tag;
    tree[rs].tag+=tree[p].tag;
    tree[p].tag=0;
}
void push_up(int p,int l,int r)
{
    tree[p].ans=tree[ls].ans+tree[ls].tag*(mid-l+1)+tree[rs].ans+tree[rs].tag*(r-mid);
}
int query(int l,int r,int left,int right,int p)
{
    if(l==left&&r==right)
    {
        tree[p].ans+=tree[p].tag;
        tree[p].tag=0;
        return tree[p].ans;
    }
    push_down(p);
    int res=0;
    if(right<=mid) res=query(l,mid,left,right,ls);
    else if(left>mid) res=query(mid+1,r,left,right,rs);
    else res=query(l,mid,left,mid,ls)+query(mid+1,r,mid+1,right,rs);
    push_up(p,l,r);
    return res;
}
void update(int l,int r,int left,int right,int p,int val)
{
    if(l==left&&r==right)
    {
        tree[p].tag+=val;
        return;
    }
    if(right<=mid) update(l,mid,left,right,ls,val);
    else if(left>mid) update(mid+1,r,left,right,rs,val);
    else update(l,mid,left,mid,ls,val),update(mid+1,r,mid+1,right,rs,val);
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    build(1,n,1);
    int m;
    cin>>m;
    while(m--)
    {
    	int op,l,r;
    	cin>>op>>l>>r;
    	if(op==1)
    	{
    		int x;
    		cin>>x;
    		update(1,n,l,r,1,x);
		}
    	else
    	{
    		cout<<query(1,n,l,r,1)<<"\n";
		}
	}
    return 0;
}
2025/1/4 20:20
加载中...