Description
有这么一群人决定随便做点什么。他们逐渐站成了一排。
而现在我们想知道每个人加入队伍后整个局面的友善值。
为了简化,我们这么描述这个问题:有n个无聊的人,对于一条长为m(n<=m)的线段,这n个人依次站到自己的位置上,其中第i个人位于位置pi(1<=pi<=m)上,且他的无聊值为bi(0<=bi<2^31)。我们定义一个队伍的友善值为每对相邻的人的契合度之和。两个人的契合度定义为他们的无聊值的异或值。
我们要知道的是在每个人加入之后整个队伍的友善值。为了更方便确认你能够得到答案,输出每个人加入后整个队伍的友善值的异或和即可。
Input
第1行:2个非负整数n,m,表示无聊的人数和线段的长度。
第2至n+1行:第i+1行2个整数表示第i个人的位置pi和无聊值bi。
Output
输出一个整数表示每个人加入后队伍的友善值的异或和。
Sample Input
5 10 10 7 1 7 9 1 2 6 8 0
Sample Output
12
Data Constraint
对于30%的数据,m,n<=1000
对于60%的数据,m,n<=100000
对于100%的数据,n<=1000000,m<=2000000,n<=m
并且对于任意i,j(1<=i<j<=n),有pi>pj或pi<pj
Solution
1.线段树:可能会时超
2.倒着做+链表删除操作
Code
#include<cstdio>
#include<algorithm>
#define I int
#define F(i,a,b) for(register int i=a;i<=b;++i)
#define Fd(i,a,b) for(register int i=a;i>=b;--i)
#define N 1000002
using namespace std;
I n,m,nx[N<<1],ls[N<<1],id[N<<1];
long long ans,now;
struct node{I x,y,z;}a[N],b[N];
I cmp(node a,node b){return a.x<b.x;}
I R(I &x){
x=0;char ch=getchar();for(;ch<'0'||ch>'9';ch=getchar()) ;
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
}
I main(){
R(n),R(m);
F(i,1,n) R(a[i].x),R(a[i].y),b[i]=a[i],b[i].z=i;
sort(b+1,b+1+n,cmp);
F(i,1,n){
id[b[i].x]=b[i].z;if(i>1) ls[b[i].x]=b[i-1].x;
if(i<n) now+=b[i].y^b[i+1].y,nx[b[i].x]=b[i+1].x;
}
ans=now;
Fd(i,n,2){
I z=a[i].x,x=ls[z],y=nx[z];
if(x) now-=a[i].y^a[id[x]].y;
if(y) now-=a[i].y^a[id[y]].y;
if(x&&y) now+=a[id[x]].y^a[id[y]].y;
nx[x]=y,ls[y]=x;
ans^=now;
}
printf("%lld\n",ans);
return 0;
}