您的位置:首页 > 其它

[BZOJ3211] 花神游历各国/[BZOJ3038] 上帝造题的七分钟2

2015-08-17 21:10 573 查看

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=3038

http://www.lydsy.com/JudgeOnline/problem.php?id=3211

题目大意

给一个序列,支持两种操作

1.对[L,R]内的数求和

2.对[L,R]内的每一个a[i]变为sqrt(a[i])

题解

对于一个数一直开根号的话101210^{12}只要开7次就会变为1

如果是0或10或1的话无论怎么开都没有意义

所以我们设置的tag为所在区间是否都为0或1

如果都是那么不进行修改,否则继续向下修改

代码

双倍经验就只上一个了

[BZOJ3038] 上帝造题的七分钟2

var
w:array[0..600000,1..4]of int64;
x:array[0..100000]of int64;
i,j,k:longint;
n,m:longint;
a,b,c,d:longint;
procedure build(a,l,r:longint);
var mid:longint;
begin
w[a,1]:=l; w[a,2]:=r;
if l=r
then begin
w[a,3]:=x[l];
if x[l]<=1
then w[a,4]:=1 else w[a,4]:=0;
exit;
end;
mid:=(l+r)>>1;
build(a*2,l,mid); build(a*2+1,mid+1,r);
w[a,3]:=w[a*2,3]+w[a*2+1,3];
if (w[a*2,4]=1)and(w[a*2+1,4]=1)
then w[a,4]:=1 else w[a,4]:=0;
end;

procedure update(a,l,r:longint);
var mid:longint;
begin
if w[a,4]=1 then exit;
if w[a,1]=w[a,2]
then begin
w[a,3]:=trunc(sqrt(w[a,3]));
if w[a,3]<=1
then w[a,4]:=1 else w[a,4]:=0;
exit;
end;
mid:=(w[a,1]+w[a,2])>>1;
if r<=mid then update(a*2,l,r) else
if l>mid then update(a*2+1,l,r)
else begin update(a*2,l,mid); update(a*2+1,mid+1,r) end;
w[a,3]:=w[a*2,3]+w[a*2+1,3];
if (w[a*2,4]=1)and(w[a*2+1,4]=1)
then w[a,4]:=1 else w[a,4]:=0;
end;

function query(a,l,r:longint):int64;
var mid:longint;
begin
if (w[a,1]=l)and(w[a,2]=r) then exit(w[a,3]);
mid:=(w[a,1]+w[a,2])>>1;
if r<=mid then exit(query(a*2,l,r)) else
if l>mid then exit(query(a*2+1,l,r))
else exit(query(a*2,l,mid)+query(a*2+1,mid+1,r));
end;

begin
readln(n);
for i:=1 to n do
read(x[i]);
build(1,1,n);
readln(m);
for i:=1 to m do
begin
readln(a,b,c);
if b>c
then begin d:=b; b:=c; c:=d; end;
case a of
1:begin writeln(query(1,b,c)); end;
0:begin update(1,b,c); end;
end;
end;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: