记录编号 229766 评测结果 AAAAAAAAAA
题目名称 马拉松 最终得分 100
用户昵称 Gravatarliu_runda 是否通过 通过
代码语言 C++ 运行时间 3.055 s
提交时间 2016-02-20 18:32:04 内存使用 3.89 MiB
显示代码纯文本
#include<cstdio>
#define min(a,b) a<b?a:b 
#define lch(x) x<<1
#define rch(x) x<<1|1
const int maxn=100005;
struct point{
	int x,y;
}lst[maxn];
inline int abs(int x){
	if(x>=0)return x;
	else return -x;
}
int read(){
	char ch;int x;bool minus=false;
	while(ch=getchar(),(ch>'9'||ch<'0')&&ch!='-');
	if(ch=='-'){
		minus=true;
		ch=getchar();
	}
	x=ch-48;
	while(ch=getchar(),ch<='9'&&ch>='0')x=x*10+ch-48;
	if(minus)x=-x;
	return x;
}
int dis[maxn];//dis[i]:i号检查站到i+1号的距离 
int _dis[maxn];//_dis[i]:检查站i ->i+2的距离 
int st_dis[maxn<<2];
int st_delta[maxn<<2];
//实现求不跳过检查站时距离的线段树
void build_dis(int rt,int l,int r){
	if(l==r)st_dis[rt]=dis[l];
	else{
		int mid=(l+r)>>1;
		build_dis(lch(rt),l,mid);
		build_dis(rch(rt),mid+1,r);
		st_dis[rt]=st_dis[lch(rt)]+st_dis[rch(rt)];
	}
} 
int query_dis(int rt,int l,int r,const int &a,const int &b){
	if(a<=l&&r<=b)return st_dis[rt];
	else{
		int mid=(l+r)>>1;
		if(b<=mid)return query_dis(lch(rt),l,mid,a,b);
		if(a>mid) return query_dis(rch(rt),mid+1,r,a,b);
		return query_dis(lch(rt),l,mid,a,b)+query_dis(rch(rt),mid+1,r,a,b);
	}
}
void update_dis(int rt,int l,int r,const int &pos,const int &newdis){
	if(l==pos&&r==pos){
		st_dis[rt]=newdis;
	}else{
		int mid=(l+r)>>1;
		if(pos<=mid)update_dis(lch(rt),l,mid,pos,newdis);
		else update_dis(rch(rt),mid+1,r,pos,newdis);
		st_dis[rt]=st_dis[lch(rt)]+st_dis[rch(rt)];
	}
}
//实现求最大缩减距离的线段树
void build_delta(int rt,int l,int r){
	if(l==r)st_delta[rt]=_dis[l]-dis[l]-dis[l+1];//跳过第l/r号检查站的下一个检查站,变化量为负:缩短 
	else {
		int mid=(l+r)>>1;
		build_delta(lch(rt),l,mid);
		build_delta(rch(rt),mid+1,r);
		st_delta[rt]=min(st_delta[lch(rt)],st_delta[rch(rt)]);
	}
}
int query_delta(int rt,int l,int r,int a,int b){
	if(a<=l&&r<=b)return st_delta[rt];
	else{
		int mid=(l+r)>>1;
		if(b<=mid)return query_delta(lch(rt),l,mid,a,b);
		if(a>mid)return query_delta(rch(rt),mid+1,r,a,b);
		return min(query_delta(lch(rt),l,mid,a,b),query_delta(rch(rt),mid+1,r,a,b));
	}
}
void update_delta(int rt,int l,int r,int pos,int newdelta){
	if(l==pos&&r==pos){
		st_delta[rt]=newdelta;
	}else{
		int mid=(l+r)>>1;
		if(pos<=mid)update_delta(lch(rt),l,mid,pos,newdelta);
		else update_delta(rch(rt),mid+1,r,pos,newdelta);
		st_delta[rt]=min(st_delta[rch(rt)],st_delta[lch(rt)]);
	}
	
}
int main(){
	freopen("marathona.in","r",stdin);
	freopen("marathona.out","w",stdout);
	//input
	int n,q,a,b;char buf[5];
	n=read();q=read();
	int lim=n-1;
	for(int i=1;i<=n;++i){
		lst[i].x=read();
		lst[i].y=read();
	}
	if(n==1){
		goto lb;
	}
	//init
	for(int i=1;i<n;++i){
	//	printf("%d %d ",abs(lst[i+1].x-lst[i].x),abs(lst[i+1].y-lst[i].y));
		dis[i]= abs(lst[i+1].x-lst[i].x) + abs(lst[i+1].y-lst[i].y);
	}//printf("\n");
	for(int i=1;i<lim;++i)_dis[i]=abs(lst[i+2].x-lst[i].x)+abs(lst[i+2].y-lst[i].y);
	//build st
	build_dis(1,1,n-1);//跑n-1段 
	build_delta(1,1,n-2);//有n-2个检查站可跳过 
	//deal with queries
	lb:
	while(q--){
		scanf("%s",buf);
		if(buf[0]=='Q'){
			a=read();b=read();
			if(a==b)printf("0\n");
			else if(a+1==b)printf("%d\n",query_dis(1,1,n-1,a,b-1));
			else printf("%d\n",query_dis(1,1,n-1,a,b-1)+query_delta(1,1,n-2,a,b-2));
		}else{
			a=read();
			lst[a].x=read();
			lst[a].y=read();
			if(n==1)continue;
			if(a!=1){
				dis[a-1]=abs(lst[a-1].x-lst[a].x) + abs(lst[a-1].y-lst[a].y);
				update_dis(1,1,n-1,a-1,dis[a-1]);
			}
			if(a!=n){
				dis[a]=abs(lst[a+1].x-lst[a].x) + abs(lst[a+1].y-lst[a].y);
				update_dis(1,1,n-1,a,dis[a]);
			}
			int delta;
			if(a-2>=1){
				_dis[a-2]=abs(lst[a-2].x-lst[a].x)+abs(lst[a-2].y-lst[a].y);
				delta=_dis[a-2]-dis[a-2]-dis[a-1];
				update_delta(1,1,n-2,a-2,delta);
			}
			if(a-1>=1&&a<n){
				_dis[a-1]=abs(lst[a-1].x-lst[a+1].x)+abs(lst[a-1].y-lst[a+1].y);
				delta=_dis[a-1]-dis[a-1]-dis[a];
				update_delta(1,1,n-2,a-1,delta);
			}
			if(a<n-1){
				_dis[a]=abs(lst[a+2].x-lst[a].x)+abs(lst[a+2].y-lst[a].y);
				delta=_dis[a]-dis[a]-dis[a+1];
				update_delta(1,1,n-2,a,delta);
			}
			
			
		}
	}
	fclose(stdin);fclose(stdout);
	return 0;
}