数据结构总结之线段树

来源:互联网 发布:手机远程桌面软件 编辑:程序博客网 时间:2024/05/21 06:58

感觉自己平时写的线段树太冗杂了,虽然时间不差,但代码量太大,操作修改还分单点和区间,于是用了点时间,把代码风格重新改了一下,简洁明了,将区间操作扩展为支持单点操作,去掉了无用的判重,在此作为模版!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int n = 1000000;
struct lx
{
    int l,r;
    long long data,lazy;
};
lx xds[n];
int a,b,pd,m,nn;
long long sz[n],ans_qjcx;
void build(int l,int r ,int k)//建造一棵区间为l-r的线段树
{
    xds[k].l = l;
    xds[k].r = r;
    if (l == r)
    {
        xds[k].data = sz[l];
        return;
    }
    int midn = (l + r) >> 1;
    build(l,midn,k << 1);
    build(midn+1,r,(k << 1) + 1);
    if (l != r) xds[k].data = xds[k << 1].data + xds[(k << 1) + 1].data;
}
void xfbj(int x)//将x号节点的lazy标记下放
{
    xds[x << 1].lazy += xds[x].lazy;
    xds[(x << 1) + 1].lazy += xds[x].lazy;
    xds[x << 1].data += (xds[x << 1].r - xds[x << 1].l + 1) * xds[x].lazy;
    xds[(x << 1) + 1].data += (xds[(x << 1) + 1].r - xds[(x << 1) + 1].l + 1) * xds[x].lazy;
    xds[x].lazy = 0;
}
void qjcx(int l,int r,int k)//查询l-r区间的和,返回值位于全局变量ans_qjcx
{
    if (xds[k >> 1].lazy) xfbj(k >> 1);
    if (xds[k].l == l && xds[k].r == r)
    {
        ans_qjcx += xds[k].data;
        return;
    }
    int midn = (xds[k].l + xds[k].r) >> 1;
    if (r <= midn) qjcx(l,r,k << 1);
    else if (l > midn) qjcx(l,r,(k << 1) + 1);
    else
    {
        qjcx(l,midn,k << 1);
        qjcx(midn + 1,r,(k << 1) + 1);
    }
}
void qjxg(int l,int r,int k,int zj)
{
    xds[k].data += zj * (r - l + 1);
    if (xds[k].l == l && xds[k].r == r)
    {
        xds[k].lazy += zj;
        return;
    }
    int midn = (xds[k].l + xds[k].r) >> 1;
    if (r <= midn) qjxg(l,r,k << 1,zj);
    else if (l > midn) qjxg(l,r,(k << 1) + 1,zj);
    else
    {
        qjxg(l,midn,k << 1,zj);
        qjxg(midn + 1,r,(k << 1) + 1,zj);
    }
}
void sread()
{
    scanf("%d",&nn);
    for(int i = 1;i <= nn;i++)
        scanf("%d",&sz[i]);
    build(1,nn,1);
    scanf("%d",&m);
    for (int i = 1;i <= m;i++)
    {
        scanf("%d",&pd);
        if (pd == 1)
        {
            int jz = 0;
            scanf("%d%d%d",&a,&b,&jz);
            qjxg(a,b,1,jz);
        }else
        {
            scanf("%d%d",&a,&b);
            ans_qjcx = 0;
            qjcx(a,b,1);
            printf("%lld\n",ans_qjcx);
        }
    }
}
int main()
{
    sread();
    return 0;
}
0 0
原创粉丝点击