记录编号 106091 评测结果 AAAAAAAAAA
题目名称 [SGU U313]环形铁路 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.227 s
提交时间 2014-06-13 09:47:06 内存使用 2.60 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const ll SIZEN=50010;
ll N,L;
ll modN(ll x){
	x=x%N;
	if(x<=0) x+=N;
	return x;
}
ll modL(ll x){
	x=x%L;
	if(x<=0) x+=L;
	return x;
}
class BD{//建筑物
public:
	ll pos;//位置
	ll id;//编号
};
bool operator < (BD a,BD b){
	return a.pos<b.pos;
}
ll upper(BD *s,ll x,ll l,ll r){//第一个位置不小于x的
	if(l==r) return l;
	ll mid=(l+r)>>1;
	if(s[mid].pos>=x) return upper(s,x,l,mid);
	else return upper(s,x,mid+1,r);
}
ll upper(BD *s,ll x){//第一个不小于x的
	x=modL(x);
	if(s[N].pos<x) return 1;
	return upper(s,x,1,N);
}
ll lower(BD *s,ll x,ll l,ll r){//最后一个位置不大于x的
	if(l==r) return l;
	ll mid=(l+r)>>1;
	if(s[mid+1].pos<=x) return lower(s,x,mid+1,r);
	else return lower(s,x,l,mid);
}
ll lower(BD *s,ll x){//最后一个不大于x的
	x=modL(x);
	if(s[1].pos>x) return N;
	return lower(s,x,1,N);
}
ll event[SIZEN]={0};//当x1对应yi时,比对应yi-1多出的部分
BD X[SIZEN],Y[SIZEN];
ll matchx[SIZEN]={0};
ll dist(ll a,ll b){//xa~yb
	ll t=abs(X[a].pos-Y[b].pos);
	return min(t,L-t);
}
ll simulate(ll k){
	ll ans=0;
	ll i=1;
	while(i<=N){
		matchx[X[i].id]=Y[k].id;
		ans+=dist(i,k);
		i++,k++;
		if(k>N) k-=N;
	}
	return ans;
}
void work(void){
	ll ans=simulate(1),ansp=1;
	ll now=ans;
	for(ll i=2;i<=N;i++){
		now+=event[i];
		if(now<ans) ans=now,ansp=i;
	}
	printf("%lld\n",simulate(ansp));
	//for(ll i=1;i<=N;i++) printf("%lld ",matchx[i]);printf("\n");
}
void prepare_X(void){//我们把所有的L都算在X这边
	for(ll i=1;i<=N;i++){
		ll a=X[i].pos,t;
		if(a*2<=L){//位于前半段
			t=upper(Y,1);//当xi对应yt时,i的贡献从L+a变成了a
			//此时x1对应y(t-(i-1))
			event[modN(t-(i-1))]-=L;
			t=upper(Y,a);//当xi对应yt时,i的贡献从a变成了-a
			event[modN(t-(i-1))]-=2*a;
			t=upper(Y,a+(L+1)/2);//当xi对应yt时,i的贡献从-a变成了L+a
			event[modN(t-(i-1))]+=L+2*a;
		}
		else{//位于后半段
			t=upper(Y,1);//当xi对应yt时,i的贡献从-a变成了L-a
			event[modN(t-(i-1))]+=L;
			t=upper(Y,a-L/2);//当xi对应yt时,i的贡献从L-a变成了a
			event[modN(t-(i-1))]+=2*a-L;
			t=upper(Y,a);//当xi对应yt时,i的贡献从a变成了-a
			event[modN(t-(i-1))]-=2*a;
		}
	}
}
void prepare_Y(void){
	for(ll i=1;i<=N;i++){
		ll b=Y[i].pos,t;
		if(b*2<=L){
			t=lower(X,b);//当yi对应xt时,i的贡献从-b变成了b
			event[modN(i-(t-1))]+=2*b;
			t=lower(X,b+(L-1)/2);//当yi对应xt时,i的贡献从b变成了-b
			event[modN(i-(t-1))]-=2*b;
		}
		else{
			t=lower(X,b-(L+2)/2);//当yi对应xt时,i的贡献从b变成了-b
			event[modN(i-(t-1))]-=2*b;
			t=lower(X,b);//当yi对应xt时,i的贡献从-b变成了b
			event[modN(i-(t-1))]+=2*b;
		}
	}
}
void read(void){
	scanf("%lld%lld",&N,&L);
	for(ll i=1;i<=N;i++) scanf("%lld",&X[i].pos),X[i].id=i;
	for(ll i=1;i<=N;i++) scanf("%lld",&Y[i].pos),Y[i].id=i;
	sort(X+1,X+1+N);
	sort(Y+1,Y+1+N);
}
int main(){
	freopen("circularrailway.in","r",stdin);
	freopen("circularrailway.out","w",stdout);
	read();
	prepare_X();
	prepare_Y();
	work();
	return 0;
}