这题花了我一个下午+半个晚上,结果改到最后我发现是空间开小了。。。mdzz
好累啊,,我直接贴了。。
题解:
代码:
var
//i,j,k,p,n,m:longint;
c:Array[0..21,0..2150005]of longint;
a:Array[0..100005]of longint;
b:array[0..21]of longint;
i,j,n,m,x,y,p:longint;
ans,v,s1:int64;
procedure swap(var x,y:longint);
var
t:longint;
begin
t:=x;
x:=y;
y:=t;
end;
function lowbit(x:longint):longint;
begin
exit(x and (-x));
end;
procedure change(p,k,v:longint);
var
v1:longint;
begin
v1:=1<<(p+1);
while (k<=v1)do
begin
inc(c[p,k],v);
k:=k+lowbit(k);
end;
end;
function gets(p,k:longint):longint;
var
s:longint;
begin
s:=0;
while (k>0)do
begin
inc(s,c[p,k]);
dec(k,lowbit(k));
end;
exit(s);
end;
procedure turn(x,v:longint);
var
j,v1:longint;
begin
for j:=0 to 20 do
begin
v1:=1<<j;
change(j,a[x] mod (v1*2)+1,v);
end;
end;
function find(p,l,r:longint):longint;
var
v:longint;
begin
inc(l);
inc(r);
v:=1<<(p+1);
if (l>r)then swap(l,r);
if (r<=0)then exit(gets(p,r+v)-gets(p,l+v-1))
else if (l<=0)then exit(gets(p,r)+gets(p,v)-gets(p,l+v-1))
else exit(gets(p,r)-gets(p,l-1));
end;
begin
readln(n,m);
for i:=1 to n do
begin
read(a[i]);
turn(i,1);
end;
for i:=1 to m do
begin
read(p,x,y);
if (p=1)then
begin
turn(x,-1);
a[x]:=y;
turn(x,1);
end
else
begin
ans:=0;
for j:=0 to 20 do
begin
v:=1<<j;
if ((v and y)=0)then continue;
s1:=find(j,v-x mod(v*2),v*2-x mod (v*2)-1);
ans:=ans+s1*v;
end;
writeln(ans);
end;
end;
end.
虽然感觉很马虎,但是今天让我非常无语。。没有心情写题解。。。