题意:
有n个无聊的人,对于一条长为m(n<=m)的线段,这n个人依次站到自己的位置上,其中第i个人位于位置pi(1<=pi<=m)上,且他的无聊值为bi(0<=bi<2^31)。我们定义一个队伍的友善值为每对相邻的人的契合度之和。两个人的契合度定义为他们的无聊值的异或值。
我们要知道的是在每个人加入之后整个队伍的友善值。为了更方便确认你能够得到答案,输出每个人加入后整个队伍的友善值的异或和即可
对于100%的数据,n<=1000000,m<=2000000,n<=m
思路:
位运算,然后从后往前一个个做,用指针指向前面和后面的数,求出异或值就好了。
关于本题:
一开始看到这题我是很懵逼的,位运算????,我大概就只知道原理,不是很熟悉,看题目看了我半天,什么这里异或一下,那里搞一下的,然后这题又要反着想,然后我就gg了,不过听了讲课以后就ac了,不过今天有点坑,改了三题正解,然后结果就对了一题。然后…….所以这里就一题了。
程序:
const
maxn=2000000;
var
i,j,n,m,x,y,z:longint;
ans,sum:int64;
a,b,c,p,q:array [1..maxn] of longint;
begin
readln(n,m);
fillchar(c,sizeof(c),255);
for i:=1 to n do
begin
readln(a[i],b[i]);
c[a[i]]:=b[i];
end;
for i:=1 to m do
if c[i]<>-1 then
begin
if x<>0 then sum:=sum+(c[x] xor c[i]);
p[i]:=x;
x:=i;
end;
ans:=ans xor sum;
x:=0;
for i:=m downto 1 do
if c[i]<>-1 then
begin
q[i]:=x;
x:=i;
end;
for i:=n downto 1 do
begin
x:=0; y:=0; z:=0;
if (p[a[i]]<>0) and (q[a[i]]<>0) then z:=(c[p[a[i]]] xor c[q[a[i]]]);
if p[a[i]]<>0 then
begin
x:=(c[p[a[i]]] xor b[i]);
q[p[a[i]]]:=q[a[i]];
end;
if q[a[i]]<>0 then
begin
y:=(c[q[a[i]]] xor b[i]);
p[q[a[i]]]:=p[a[i]];
end;
sum:=sum-x-y+z;
ans:=ans xor sum;
end;
writeln(ans);
end.