蒟蒻玄关10分求调

P3372 【模板】线段树 1

gdfz02sjy @ 2024-11-29 17:52:30

#include<bits/stdc++.h>
using namespace std;
const int N=100005;
long long a,b,c,d,e,f;
//开始建树 
    int n,w[N];
    struct node{
        int l,r,sum,add;
    };
node tr[N*4];//开数组
void push_up(int p){
    //向上修改
    tr[p].sum=tr[p<<1].sum+tr[p<<1|1].sum;//保证出现超级树叶“叶传叶”的现象
    //从上到下确认 
}
void push_down(int p){
    //向下更新 
    if(tr[p].add){
        tr[p<<1].sum+=tr[p].add*(tr[p<<1].r-tr[p<<1].l+1);
        tr[p<<1|1].sum+=tr[p].add*(tr[p<<1|1].r-tr[p<<1].l+1);
        tr[p<<1].add+=tr[p].add;
        tr[p<<1|1].add+=tr[p].add;
        tr[p].add=0;
    } 
}
void build(int p,int il,int ir){//建树函数 
    //il是输入的左子树(叶子),ir是输入的右子树(叶子)
    tr[p]={il,ir,w[il]};
    if(il==ir)return ;//如果是叶子,那么就是到底了,可以返回 
    int m=il+ir>>1;//不是叶子,退化成子树,继续往下找
    build(p<<1,il,m);
    build(p<<1|1,m+1,ir);
    //左子树延伸和右子树的延伸 
    push_up(p);//超级叶子的感染 
    return ;    
}
//建树结束,开始修改点
void updata(int p,int x,int y,int k){
    //x代表需要寻找到的“黄金叶子”,k代表“黄金叶子”的修改方式 
    //点的修改
    if(tr[p].l>=x&&tr[p].r<=y){//确认是否到达目标“黄金叶子” 
        //开始“黄金叶子”的探索
        tr[p].sum+=((tr[p].r-tr[p].l+1)*k);//改造“黄金叶子” 
        tr[p].add+=k;//给黄金叶子升级为超级叶子 
        return ;//叶子修改完毕 
    } 
    int m=tr[p].l+tr[p].r>>1;
    push_down(p);
    if(x<=m)updata(p<<1,x,y,k);//在根的左边寻找“黄金叶子”
    if(y>m)updata(p<<1|1,x,y,k);//在根的右边寻找“黄金叶子”
    push_up(p);//超级叶子开始感染
    return ; 
} 
//修改结束,开始查询 
int querty(int p,int x,int y){//区间查询 
    if(x<=tr[p].l&&tr[p].r<=y)return tr[p].sum;//覆盖则返回
    int m=tr[p].l+tr[p].r>>1;//不覆盖则继续退化成树枝
    push_down(p);
    int sum=0;//初始化
    if(x<=m)sum+=querty(p<<1,x,y);//往左查询“黄金树叶”
    if(y>m)sum+=querty(p<<1|1,x,y);//往右查询“ 黄金树叶” 
    return sum;
} 
int main(){
    cin>>a>>b;
    for(int i=1;i<=a;i++)cin>>w[i];//输入 
    build(1,1,a);//建树 
    for(int i=0;i<b;i++){
        cin>>c;//输入类型
        if(c==1){
            cin>>d>>e>>f;//输入 
            updata(1,d,e,f);//运算 
        } 
        else{
            cin>>d>>e;//输入 
            cout<<querty(1,d,e)<<endl;//输出 
        }
    }
    return 0;
}

by wang6w6 @ 2024-11-29 19:23:36

你的

int m=tr[p].l+tr[p].r>>1;

为啥没有括号?不应该是

int m=(tr[p].l+tr[p].r)>>1;

吗?


by wang6w6 @ 2024-11-29 20:33:38

你的下放


void push_down(ll p){
    //向下更新 
    if(tr[p].add){
        tr[p<<1].sum+=tr[p].add*(tr[p<<1].r-tr[p<<1].l+1);
        tr[p<<1|1].sum+=tr[p].add*(tr[p<<1|1].r-tr[p<<1|1].l+1);
        tr[p<<1].add+=tr[p].add;
        tr[p<<1|1].add+=tr[p].add;
        tr[p].add=0;
    } 
}

里面的右节点

tr[p<<1].l+1);

p<<1不应该是p<<1|1吗?


|