线段树

自古美人都是妖i 提交于 2020-02-20 06:45:57
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
const int maxn = 1e5+10;

using namespace std;

int Sum[maxn<<2];//A[maxn<<2];//Sum求和,A为原数组(根据题目更改)
int num[maxn<<2];
int len;

void PushUp(int node)//向上更新节点信息
{
    Sum[node]=Sum[node<<1]+Sum[node<<1|1];
}

void pushdown(int node,int wide){
    if(num[node]){
        int t=num[node];
        num[node<<1]=t;
        num[node<<1|1]=t;
        Sum[node<<1]=(wide-(wide>>1))*t;
        Sum[node<<1|1]=(wide>>1)*t;
        num[node]=0;
    }
}


void Build(int l,int r,int node){ //[l,r]表示当前节点区间,node表示当前节点的实际存储位置
    if(l==r) {//若到达叶节点
        Sum[node]=1;//存储A数组的值
        return;
    }
    int m=(l+r)>>1;
   //左右递归
    Build(l,m,node<<1);
    Build(m+1,r,node<<1|1);
    //更新信息
    PushUp(node);
}

void update(int l,int r,int add,int L,int R,int node){//l,r为操作区间
    if(l<=L&&r>=R){
        num[node]=add;
        Sum[node]=add*(R-L+1);
        return;
    }
    pushdown(node,R-L+1);
    int m=(L+R)>>1;
    if(l <= m) update(l,r,add,R,m,node<<1);
    if(r > m) update(l,r,add,m+1,R,node<<1|1);
    PushUp(node);
}



int Query(int L,int R,int l,int r,int node){//求和
    //[L,R]表示操作区间,[l,r]表示当前区间,node表示当前节点编号
    if(L <= l && r <= R){
       //在区间内直接返回
        return Sum[node];
    }
    int m=(l+r)>>1;
    //左子区间:[l,m] 右子区间:[m+1,r]  求和区间:[L,R]
    //累加答案
    int ANS=0;
    if(L <= m) ANS+=Query(L,R,l,m,node<<1);//左子区间与[L,R]有重叠,递归
    if(R >  m) ANS+=Query(L,R,m+1,r,node<<1|1); //右子区间与[L,R]有重叠,递归
    return ANS;
}


int main()
{
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!