线段树_POJ-3468

题目链接:http://poj.org/problem?id=3468

线段树裸题。。。。

用了两种方法写:

1.lazy,效率略低

 1 #include<cstdio>

 2 #include<cstdlib>

 3 #include<cstring>

 4 #include<algorithm>

 5 using namespace std;

 6 #define lowbit(a) ((a)&(-a))

 7 #define max(a, b) ((a)>(b)?(a):(b))

 8 #define min(a, b) ((a)<(b)?(a):(b))

 9 #define MAXN 100100

10 #define PI 3.1415926

11 #define E 2.718281828

12 #define INF 0x777777f

13 typedef long long LL;

14 

15 struct tnode{

16     int lc, rc, l, r; LL data, tag;

17     void clear(){data = tag = lc = rc = 0;}

18 } tree[MAXN*4];

19 int n, m, tCnt; int a[MAXN];

20 

21 /*根据儿子的信息更新*/

22 inline void update(tnode &p){

23     p.data = tree[p.lc].data + tree[p.rc].data;

24 }

25 /*根据父亲的tag更新(注意tag类型)*/

26 inline void update(tnode &p, LL tag){

27     p.data += (p.r-p.l+1)*tag;

28 }

29 /*下传tag信息*/

30 inline void pushdown(tnode &p){

31     if (!p.tag) return; if (p.l == p.r){p.tag = 0; return;}

32     int mid = (p.l+p.r)>>1;

33     if (p.lc) {tree[p.lc].tag += p.tag; update(tree[p.lc], p.tag);}

34     if (p.rc) {tree[p.rc].tag += p.tag; update(tree[p.rc], p.tag);}

35     p.tag = 0;

36 }

37 /*建树*/

38 void build(tnode &p, int l, int r){

39     p.l = l; p.r = r;

40     if (l == r) {p.data = a[l]; return;}

41     int mid = (l+r)>>1;

42     p.lc = ++tCnt; build(tree[p.lc], l, mid);

43     p.rc = ++tCnt; build(tree[p.rc], mid+1, r);

44     update(p);

45 }

46 /*修改*/

47 void change(tnode &p, int l, int r, int x){

48     pushdown(p);

49     if (l<=p.l && p.r<=r){p.tag = x; update(p, x); return;}

50     int mid = (p.l+p.r)>>1;

51     if (l <= mid) change(tree[p.lc], l, r, x);

52     if (mid  < r) change(tree[p.rc], l, r, x);

53     update(p);

54 }

55 /*查询(注意返回类型)*/

56 LL query(tnode &p, int l, int r){

57     pushdown(p);

58     if (l<=p.l && p.r<=r) {return p.data;}

59     int mid = (p.l+p.r)>>1; LL ret = 0;

60     if (l <= mid) ret += query(tree[p.lc], l, r);

61     if (mid  < r) ret += query(tree[p.rc], l, r);

62     return ret;

63 }

64 int main(){

65     scanf("%d%d", &n, &m);

66     for (int i = 1; i <= n; i++) scanf("%d", &a[i]);

67     tCnt = 1; build(tree[1], 1, n);

68     char c = getchar(); int l, r, x;

69     for (int i = 1; i <= m; i++){

70         c = getchar();

71         if (c=='C'){

72             scanf("%d%d%d", &l, &r, &x);

73             change(tree[1], l, r, x);

74         }

75         else {

76             scanf("%d%d", &l, &r);

77             printf("%I64d\n", query(tree[1], l, r));

78         }

79         getchar();

80     }

81     return 0;

82 }

2.标记永久化,效率较高

 1 #include<cstdio>

 2 #include<cstdlib>

 3 #include<cstring>

 4 #include<algorithm>

 5 using namespace std;

 6 #define lowbit(a) ((a)&(-a))

 7 #define max(a, b) ((a)>(b)?(a):(b))

 8 #define min(a, b) ((a)<(b)?(a):(b))

 9 #define MAXN 100100

10 #define PI 3.1415926

11 #define E 2.718281828

12 #define INF 0x777777f

13 typedef long long LL;

14 

15 struct tnode{

16     int lc, rc, l, r; LL data, tag;

17     void clear(){data = tag = lc = rc = 0;}

18 } tree[MAXN*4];

19 int n, m, tCnt; int a[MAXN];

20 

21 /*建树*/

22 void build(tnode &p, int l, int r){

23     p.l = l; p.r = r;

24     if (l == r) {p.data = a[l]; return;}

25     int mid = (l+r)>>1;

26     p.lc = ++tCnt; build(tree[p.lc], l, mid);

27     p.rc = ++tCnt; build(tree[p.rc], mid+1, r);

28     /*update_p*/

29         p.data = tree[p.lc].data+tree[p.rc].data;

30     /*update_p*/

31 }

32 /*修改(l、r都在p的范围内)*/

33 void change(tnode &p, int l, int r, int v){

34     /*update_p*/

35         p.data += (r-l+1)*v;

36         if (l==p.l && p.r==r) {p.tag += v; return;}

37     /*update_p*/

38     int mid = (p.l+p.r)>>1;

39     if (r <= mid) {change(tree[p.lc], l, r, v); return;}            //全在左子树

40     if (l >  mid) {change(tree[p.rc], l, r, v); return;}            //全在右子树

41     change(tree[p.lc], l, mid, v); change(tree[p.rc], mid+1, r, v);    //越过中点

42 }

43 /*查询(注意返回类型,其他同上)*/

44 LL query(tnode &p, int l, int r){

45     if (l==p.l && p.r==r) {return p.data;}

46     int mid = (p.l+p.r)>>1; LL ret = (r-l+1)*p.tag;

47     if (r <= mid) return ret+query(tree[p.lc], l, r);

48     if (l >  mid) return ret+query(tree[p.rc], l, r);

49     return ret+query(tree[p.lc], l, mid)+query(tree[p.rc], mid+1, r);

50 }

51 int main(){

52     scanf("%d%d", &n, &m);

53     for (int i = 1; i <= n; i++) scanf("%d", &a[i]);

54     tCnt = 1; build(tree[1], 1, n);

55     char c = getchar(); int l, r, x;

56     for (int i = 1; i <= m; i++){

57         c = getchar();

58         if (c=='C'){

59             scanf("%d%d%d", &l, &r, &x);

60             change(tree[1], l, r, x);

61         }

62         else {

63             scanf("%d%d", &l, &r);

64             printf("%I64d\n", query(tree[1], l, r));

65         }

66         getchar();

67     }

68     return 0;

69 }

你可能感兴趣的:(poj)