3882. 【NOIP2014模擬】鄰近

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; 
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章