线段树的裸题;

但是操作很奇怪,开方是不能lazy tag的

看来只能暴力修改了

但注意,开放开到1的时候就不用开,立一个flag就可以了

这可以大大的优化;

其实我是来复习线段树的

 1 var tree:array[0..400010] of int64;
 2     lazy:array[0..400010] of boolean;
 3     a:array[0..100010] of int64;
 4     n,m,ch,p,q,l,r,i:longint;
 5 
 6 procedure swap(var a,b:longint);
 7   var c:longint;
 8   begin
 9     c:=a;
10     a:=b;
11     b:=c;
12   end;
13 
14 procedure update(i:longint);
15   begin
16     tree[i]:=tree[i*2]+tree[i*2+1];
17     lazy[i]:=lazy[i*2] and lazy[i*2+1];
18   end;
19 
20 procedure build(i,l,r:longint);
21   var m:longint;
22   begin
23     if l=r then
24     begin
25       tree[i]:=a[l];
26       lazy[i]:=false;
27     end
28     else begin
29       m:=(l+r) shr 1;
30       build(i*2,l,m);
31       build(i*2+1,m+1,r);
32       update(i);
33     end;
34   end;
35 
36 procedure work(i,l,r:longint);
37   var m:longint;
38   begin
39     if l=r then
40     begin
41       tree[i]:=trunc(sqrt(tree[i]));
42       if tree[i]=1 then lazy[i]:=true;
43     end
44     else begin
45       m:=(l+r) shr 1;
46       if (p<=m) and not lazy[i*2] then work(i*2,l,m);
47       if (q>m) and not lazy[i*2+1] then work(i*2+1,m+1,r);
48       update(i);
49     end;
50   end;
51 
52 function ask(i,l,r:longint):int64;
53   var m:longint;
54   begin
55     if (p<=l) and (q>=r) then exit(tree[i])
56     else begin
57       m:=(l+r) shr 1;
58       ask:=0;
59       if p<=m then ask:=ask+ask(i*2,l,m);
60       if q>m then ask:=ask+ask(i*2+1,m+1,r);
61     end;
62   end;
63 
64 begin
65   readln(n);
66   for i:=1 to n do
67     read(a[i]);
68   build(1,1,n);
69   readln(m);
70   for i:=1 to m do
71   begin
72     readln(ch,p,q);
73     if p>q then swap(p,q);
74     if ch=0 then
75       work(1,1,n)
76     else if ch=1 then
77       writeln(ask(1,1,n));
78   end;
79 end.
View Code

 

posted on 2014-05-02 23:43  acphile  阅读(186)  评论(0编辑  收藏  举报