【模板】线段树

来源:互联网 发布:淘宝落地窗帘布 编辑:程序博客网 时间:2024/06/03 05:06

线段树 处理区间问题的高级数据结构
听说树状数组能做(树状数组我不会啊QAQ )的线段树都能做,就丢个线段树吧QAQ
快NOIP了还是好弱怎么办 急在线等
NOIP Loiers RP ++!!

void up(int p)//更新数据{    tree[p].sum = tree[p<<1].sum + tree[p<<1|1].sum;    tree[p].max = max(tree[p<<1].max,tree[p<<1|1].max);    tree[p].min = min(tree[p<<1].min,tree[p<<1|1].min);}void push(int p)//标记下放{    tree[p<<1].sum += tree[p].add * (tree[p<<1].r - tree[p<<1].l + 1);    tree[p<<1].add += tree[p].add;    tree[p<<1|1].sum += tree[p].add * (tree[p<<1|1].r - tree[p<<1|1].l + 1);    tree[p<<1|1].add += tree[p].add;    tree[p].add = 0;} void build(int p,int l,int r)//建树{    tree[p].l = l;    tree[p].r = r;    if(l == r)    {        tree[p].min = tree[p].max = tree[p].sum = num[l];        return ;    }    int mid = (l + r) >> 1;    build(p<<1,l,mid);    build(p<<1|1,mid+1,r);    up(p);}void change_qujian(int p,int l,int r,int v)//区间修改{    if(l <= tree[p].l && tree[p].r <= r)    {        tree[p].sum += v * (tree[p].r - tree[p].l +1);        tree[p].max += v;        tree[p].min += v;        tree[p].add += v;        return;    }    push(p);    int mid = (tree[p].l + tree[p].r) >> 1;    if(l <= mid ) change(p<<1,l,r,v);    if(mid < r) change(p<<1|1,l,r,v);    up(p);}void change_dian(int p,int a,int x)//单点修改{    if(a==tree[p].l&&tree[p].r==a)    {        tree[p].sum+=x;        tree[p].add+=x;        return;    }    push(p);    int mid = (tree[p].l+tree[p].r)/2;    if(a <= mid) change(p*2,a,x);    if(mid < a) change(p*2+1,a,x);    up(p);}ll ask(int p,int l)//单点查询{    if(l == tree[p].l && tree[p].r == l)    {        return tree[p].sum;    }    push(p);    int mid = (tree[p].l + tree[p].r)/2;    ll ans = 0;    if(l <= mid) ans += ask(p*2,l);    if(mid < l) ans += ask(p*2+1,l);    return ans;}ll ask_min(int p,int l,int r)//区间最小值{    if(l <= tree[p].l && tree[p].r <= r)    {        return tree[p].min;    }    push(p);    int mid = (tree[p].l + tree[p].r) >> 1;    ll ans = 21474836472333333;    if(l <= mid) ans = min(ans,ask_min(p<<1,l,r));    if(mid < r) ans = min(ans,ask_min(p<<1|1,l,r));    return ans;}ll ask_max(int p,int l,int r)//区间最大值{    if(l <= tree[p].l && tree[p].r <= r)    {        return tree[p].max;    }    push(p);    int mid = (tree[p].l + tree[p].r) >> 1;    ll ans = 0;    if(l <= mid) ans = max(ans,ask_max(p<<1,l,r));    if(mid < r) ans = max(ans,ask_max(p<<1|1,l,r));    return ans;}ll ask_sum(int p,int l,int r)//区间求和{    if(l <= tree[p].l && tree[p].r <= r)    {        return tree[p].sum;    }    push(p);    int mid = (tree[p].l + tree[p].r) >> 1;    ll ans = 0;    if(l <= mid) ans += ask_sum(p<<1,l,r);    if(mid < r) ans += ask_sum(p<<1|1,l,r));    return ans;}
0 0
原创粉丝点击