[POJ1195 Mobile phones]

[题目来源]:IOI 2001

[关键字]:线段树

[题目大意]:对于一个矩形,一开始全是0,然后会有操作:1、在(x,y)加上某个数;2、查找(l,r)到(b,t)这一子矩形中数字的和。

//=====================================================================================================

[分析]:用线段树或树状数组进行区间的变更或求和操作,由于是一个二维的所以将每个区间的值改成一个数组记录另一维。每次插入都回直接插入到树的叶子上,所以只要在回溯时顺便更新就行,不用延迟。

[代码]:

线段树
 1 program Project1;
2 type
3 rec = record
4 x, y, lc, rc: longint;
5 dat: array[0..1200] of longint;
6 end;
7 var
8 n, ans, tot: longint;
9 tree: array[0..5000] of rec;
10
11 procedure build(l, r: longint);
12 var
13 now: longint;
14 begin
15 inc(tot);
16 now := tot;
17 tree[now].x := l;
18 tree[now].y := r;
19 if l+1 <= r then
20 begin
21 tree[now].lc := tot+1;
22 build(l,(l+r) div 2);
23 tree[now].rc := tot+1;
24 build((l+r) div 2+1,r);
25 end;
26 end;
27
28 procedure ins(v, x, y, dat: longint);
29 begin
30 if (y = tree[v].x) and (tree[v].y = y) then
31 begin
32 tree[v].dat[x] := tree[v].dat[x]+dat;
33 exit;
34 end;
35 // writeln(tree[v].x,'',tree[v].y);
36 if y <= (tree[v].x+tree[v].y) div 2 then ins(tree[v].lc,x,y,dat);
37 if y > (tree[v].x+tree[v].y) div 2 then ins(tree[v].rc,x,y,dat);
38 tree[v].dat[x] := tree[v].dat[x]+dat;
39 end;
40
41 procedure find(v, l, r, b, t: longint);
42 var
43 i: longint;
44 begin
45 if (b <= tree[v].x) and (tree[v].y <= t) then
46 begin
47 for i := l to r do
48 ans := ans+tree[v].dat[i];
49 //writeln(tree[v].x,'',tree[v].y,'',ans);
50 exit;
51 end;
52 //writeln(tree[v].x,'',tree[v].y);
53 if b <= (tree[v].x+tree[v].y) div 2 then find(tree[v].lc,l,r,b,t);
54 if t > (tree[v].x+tree[v].y) div 2 then find(tree[v].rc,l,r,b,t);
55 end;
56
57 procedure init;
58 var
59 s, x, y, dat, l, r, b, t: longint;
60 begin
61 while 1 = 1 do
62 begin
63 read(s);
64 case s of
65 0: begin
66 readln(n);
67 tot := 0;
68 build(1,n);
69 end;
70 1: begin
71 readln(x,y,dat);
72 ins(1,x+1,y+1,dat);
73 end;
74 2: begin
75 readln(l,b,r,t);
76 ans := 0;
77 find(1,l+1,r+1,b+1,t+1);
78 writeln(ans);
79 end;
80 3: exit;
81 end;
82 end;
83 end;
84
85 begin
86 init;
87 end.
树状数组
 1 program Project1;
2 var
3 ans, n: longint;
4 tree: array[0..2000,0..2000] of longint;
5
6 procedure ins(x, y, dat: longint);
7 var
8 k: longint;
9 begin
10 k := y;
11 while k <= n do
12 begin
13 tree[k,x] := tree[k,x]+dat;
14 k := k+k and -k;
15 end;
16 end;
17
18 function find(l, r, y: longint):longint;
19 var
20 sum, k, i: longint;
21 begin
22 k := y;
23 sum := 0;
24 while k >= 1 do
25 begin
26 for i := l to r do
27 sum := sum+tree[k,i];
28 k := k-k and -k;
29 end;
30 exit(sum);
31 end;
32
33 procedure init;
34 var
35 s, x, y, dat, l, r, b, t: longint;
36 begin
37 while 1 = 1 do
38 begin
39 read(s);
40 case s of
41 0: readln(n);
42 1: begin
43 readln(x,y,dat);
44 ins(x+1,y+1,dat);
45 end;
46 2: begin
47 readln(l,b,r,t);
48 ans := find(l+1,r+1,t+1);
49 ans := ans-find(l+1,r+1,b);
50 writeln(ans);
51 end;
52 3: exit;
53 end;
54 end;
55 end;
56
57 begin
58 init;
59 end.




你可能感兴趣的:(mobile)