pku 3468 A Simple Problem with Integers

一道线段树的典型应用,标记真强大,没事怕错就多下放几次标记,反正没什么错。

View Code
  1 program tree_line(input,output);
2 type
3 node = record
4 sum,mark : int64;
5 left,right,x,y : longint;
6 end;
7 var
8 tree : array[0..1000000] of node;
9 n,m,tot : longint;
10 the_x,the_y,h : longint;
11 answer : int64;
12 a : array[0..100001] of longint;
13 function min(aa,bb: longint ):longint;
14 begin
15 if aa<bb then
16 exit(aa);
17 exit(bb);
18 end; { min }
19 function max(aa,bb :longint ):longint;
20 begin
21 if aa>bb then
22 exit(aa);
23 exit(bb);
24 end; { max }
25 procedure build(xx,yy: longint );
26 var
27 now,mid : longint;
28 begin
29 inc(tot);
30 now:=tot;
31 tree[now].x:=xx;
32 tree[now].y:=yy;
33 tree[now].mark:=0;
34 tree[now].sum:=0;
35 if xx=yy then
36 begin
37 tree[now].sum:=a[xx];
38 exit;
39 end;
40 mid:=(xx+yy)>>1;
41 tree[now].left:=tot+1;
42 build(xx,mid);
43 tree[now].right:=tot+1;
44 build(mid+1,yy);
45 tree[now].sum:=tree[tree[now].left].sum+tree[tree[now].right].sum;
46 end; { build }
47 procedure change(now :longint );
48 var
49 mid : longint;
50 begin
51 inc(tree[now].sum,h*(min(tree[now].y,the_y)-max(the_x,tree[now].x)+1));
52 if (tree[now].x>=the_x)and(tree[now].y<=the_y) then
53 begin
54 inc(tree[now].mark,h);
55 exit;
56 end;
57 mid:=(tree[now].x+tree[now].y)>>1;
58 if the_x<=mid then
59 change(tree[now].left);
60 if mid<the_y then
61 change(tree[now].right);
62 end; { change }
63 procedure find(now :longint );
64 var
65 mid : longint;
66 begin
67 if (tree[now].x>=the_x)and(the_y>=tree[now].y) then
68 begin
69 inc(answer,tree[now].sum);
70 exit;
71 end;
72 inc(tree[tree[now].left].mark,tree[now].mark);
73 inc(tree[tree[now].right].mark,tree[now].mark);
74 inc(tree[tree[now].left].sum,tree[now].mark*(tree[tree[now].left].y-tree[tree[now].left].x+1));
75 inc(tree[tree[now].right].sum,tree[now].mark*(tree[tree[now].right].y-tree[tree[now].right].x+1));
76 tree[now].mark:=0;
77 mid:=(tree[now].x+tree[now].y)>>1;
78 if the_y>mid then
79 find(tree[now].right);
80 if the_x<=mid then
81 find(tree[now].left);
82 end; { find }
83 procedure main;
84 var
85 i : longint;
86 ch : char;
87 begin
88 readln(n,m);
89 for i:=1 to n do
90 read(a[i]);
91 readln;
92 build(1,n);
93 for i:=1 to m do
94 begin
95 read(ch);
96 if ch='C' then
97 begin
98 readln(the_x,the_y,h);
99 change(1);
100 end;
101 if ch='Q' then
102 begin
103 readln(the_x,the_y);
104 answer:=0;
105 find(1);
106 writeln(answer);
107 end;
108 end;
109 end; { main }
110 begin
111 main;
112 end.



posted @ 2012-03-09 16:42  Codinginging  阅读(155)  评论(0编辑  收藏  举报