LYXin's Blog

Here I stand. And here I'll stay.

线段树

线段树模板啦
维护区间和,最大值,最小值
资瓷区间加值,区间赋值

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int INF = 0x3f3f3f3f;
const int maxn = 105;

int a[maxn];
int add[maxn << 2], col[maxn << 2];
int minv[maxn << 2], maxv[maxn << 2], sum[maxn << 2];

void maintain(int o, int L, int R)
{
    if(L >= R) return ;
    int lc = o << 1, rc = o << 1 | 1;
    sum[o] = sum[lc] + sum[rc];
    maxv[o] = max(maxv[lc], maxv[rc]);
    minv[o] = min(minv[lc], minv[rc]);
}

void pushdown(int o, int L, int R)
{
    if(L >= R) return ;
    int M = (L + R) >> 1, lc = o << 1, rc = o << 1 | 1;
    if(col[o])
    {
        col[lc] = col[rc] = col[o];
        add[lc] = add[rc] = 0;
        sum[lc] = col[o] * (M-L+1);
        sum[rc] = col[o] * (R-M);
        maxv[lc] = maxv[rc] = minv[lc] = minv[rc] = col[o];
        col[o] = 0;
    }
    if(add[o])
    {
        add[lc] += add[o]; add[rc] += add[o];
        sum[lc] += add[o] * (M-L+1); sum[rc] += add[o] * (R-M);
        maxv[lc] += add[o]; maxv[rc] += add[o];
        minv[lc] += add[o]; minv[rc] += add[o];
        add[o] = 0;
    }
}

int op, qv, _sum, _max, _min;

void update(int o, int L, int R, int ql, int qr)
{
    if(L == ql && qr == R)
    {
        if(op == 1)//add
        {
            add[o] += qv;
            maxv[o] += qv;
            minv[o] += qv;
            sum[o] += qv * (R-L+1);
        }
        else//set
        {
            col[o] = maxv[o] = minv[o] = qv;
            add[o] = 0;
            sum[o] = qv * (R-L+1);
        }
    }
    else
    {
        pushdown(o, L, R);
        int M = (L + R) >> 1;
        if(qr <= M) update(o << 1, L, M, ql, qr);
        else if(M < ql) update(o << 1 | 1, M+1, R, ql, qr);
        else
        {
            update(o << 1, L, M, ql, M);
            update(o << 1 | 1, M+1, R, M+1, qr);
        }
        maintain(o, L, R);
    }
}

void query(int o, int L, int R, int ql, int qr)
{
    if(L == ql && qr == R)
    {
        _sum += sum[o];
        _max = max(_max, maxv[o]);
        _min = min(_min, minv[o]);
    }
    else
    {
        pushdown(o, L, R);
        int M = (L + R) >> 1;
        if(qr <= M) query(o << 1, L, M, ql, qr);
        else if(M < ql) query(o << 1 | 1, M+1, R, ql, qr);
        else
        {
            query(o << 1, L, M, ql, M);
            query(o << 1 | 1, M+1, R, M+1, qr);
        }
        maintain(o, L, R);
    }
}

void build(int o, int L, int R)
{
    if(L == R) maxv[o] = minv[o] = sum[o] = a[L];
    else
    {
        int M = (L + R) >> 1;
        build(o << 1, L, M);
        build(o << 1 | 1, M+1, R);
        maintain(o, L, R);
    }
}

int main()
{
    freopen("input.txt","r",stdin);
    freopen("out2.txt","w",stdout);

    int n, q;
    scanf("%d%d", &n, &q);
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    build(1, 1, n);
    while(q--)
    {
        int ql, qr;
        scanf("%d", &op);
        if(op <= 2)
        {
            scanf("%d%d%d", &ql, &qr, &qv);
            update(1, 1, n, ql, qr);
        }
        else
        {
            scanf("%d%d", &ql, &qr);
            _sum = _max = 0; _min = INF;
            query(1, 1, n, ql, qr);
            printf("%d %d %d\n", _min, _max, _sum);
        }
    }

    fclose(stdin);
    fclose(stdout);
    return 0;
}
阅读更多
个人分类: templates
上一篇hdu2222
下一篇Treap
想对作者说点什么? 我来说一句

线段树ppt的好东东

2009年07月23日 140KB 下载

线段树 树状数组 数据结构

2011年07月24日 1.29MB 下载

线段树区间更新代码

2017年12月22日 2KB 下载

国家队论文——线段树

2009年06月06日 170KB 下载

帮助理解的线段树

2013年07月29日 166KB 下载

线段树入门

2018年03月29日 1.67MB 下载

线段树PPT两个,所有常规用法

2009年09月28日 97KB 下载

线段树及其应用pptppt

2011年01月29日 172KB 下载

没有更多推荐了,返回首页

关闭
关闭