码迷,mamicode.com
首页 > 其他好文 > 详细

线段树_POJ-3468

时间:2015-02-10 10:27:30      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:

题目链接: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-3468

标签:

原文地址:http://www.cnblogs.com/zhu8655/p/4283053.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!