Violet 3 杯省选模拟赛 天使玩偶

https://vjudge.net/problem/HYSBZ-2716

https://ac.nowcoder.com/acm/problem/51118

题目

Ayu 在七年前曾经收到过一个天使玩偶,当时她把它当作时间囊埋在了地下。而七年后 的今天,Ayu 却忘了她把天使玩偶埋在了哪里,所以她决定仅凭一点模糊的记忆来寻找它。

我们把 Ayu 生活的小镇看作一个二维平面坐标系,而 Ayu 会不定时地记起可能在某个点 (x,y) 埋下了天使玩偶;或者 Ayu 会询问你,假如她在 (x,y) ,那么她离近的天使玩偶可能埋下的地方有多远。

因为 Ayu 只会沿着平行坐标轴的方向来行动,所以在这个问题里我们定义两个点之间的距离为dist(A,B)=|Ax-Bx|+|Ay-By|。其中 Ax 表示点 A的横坐标,其余类似。

Input

第一行包含两个整数n和m ,在刚开始时,Ayu 已经知道有n个点可能埋着天使玩偶, 接下来 Ayu 要进行m 次操作

接下来n行,每行两个非负整数 (xi,yi),表示初始n个点的坐标。

再接下来m 行,每行三个非负整数 t,xi,yi。

如果t=1 ,则表示 Ayu 又回忆起了一个可能埋着玩偶的点 (xi,yi)。

如果t=2 ,则表示 Ayu 询问如果她在点 (xi,yi) ,那么在已经回忆出来的点里,离她近的那个点有多远

Output

对于每个t=2 的询问,在单独的一行内输出该询问的结果。

题解

因为是曼哈顿距离,所以距离可以写成$\left\lvert x-x_i\right\rvert+\left\lvert y-y_i\right\rvert$,去掉绝对值可以分成4种情况

  1. $x<x_i$,$y<y_i$
  2. $x<x_i$,$y\geqslant y_i$
  3. $x\geqslant x_i$,$y<y_i$
  4. $x\geqslant x_i$,$y\geqslant y_i$

距离就变成以下四种情况

  • $-x-y+x_i+y_i=(-x-y)-(x_i-y_i)$
  • $-x+y+x_i-y_i=(-x+y)-(-x_i+y_i)$
  • $x-y-x_i+y_i=(x-y)-(x_i-y_i)$
  • $x+y-x_i-y_i=(x+y)-(x_i+y_i)$

可以看到符号都统一了,而且距离可以分成查询的坐标和知道的坐标两部分,只用保存后面那一部分的和的最大值,就可以得到距离的最小值。

如果不考虑在序列中新增操作2,那么题目要求是在四种情况中找最大的和

可以按照x递增的方向,用树状数组保存y前缀时的最大和,这样就可以解决不考虑新增操作2的问题。

因为每个点对查询的结果都是独立的,因此按时间进行分治

左半段时间 右半段时间

calc(l,r)表示解决这段时间内所有的操作1对这段时间内所有的操作2的影响。

那么可以递归为:

  1. 只考虑左半段时间中的操作1对左半段时间的操作2的影响
  2. 只考虑右半段时间中的操作1对右半段时间的操作2的影响
  3. 处理左半段时间的操作1对右半段时间的操作2的影响

递归中需要对操作按照x排序,因此时间复杂度是$T(n)=2T(n/2)+\mathcal{O}(n\log n)=\mathcal{O}(n\log^2 n)$

由于是递归,所以可以把排序改为归并,去掉多余的$\log(n)$,时间复杂度是$T(n)=2T(n/2)+\mathcal{O}(n)=\mathcal{O}(n\log n)$

还要注意会不会出现坐标0导致树状树组死循环

这中间用了很多卡常的办法,比如memset代替for循环复制,因为结构体可能会有对齐的问题,所以用了强制转换指针……

本来是个例题,结果要卡常,还是厉害

(KD-Tree以后再看吧……)

AC代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define REP(i,a,b) for(register int i=(a); i<(b); i++)
#define REPE(i,a,b) for(register int i=(a); i<=(b); i++)
using namespace std;
#define MAXN 1000007
#define INF 0x3fffffff
struct node {
	int x,y,id;bool v;
	bool operator<(const node &r) const {
		return x<r.x || (x==r.x && y<r.y);
	}
} op[MAXN], bk[MAXN], tm[MAXN]; int opn;
int ans[MAXN];
char buf[1<<21], *p1=buf, *p2=buf;
#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin)),p1==p2?EOF:*p1++)//无聊的读写挂……
template <class T>
inline void read(T&x) {
	x=0; char ch; do ch=gc(); while(ch<=' ');
	while(ch>' ') {x=x*10+ch-'0'; ch=gc();}
}
template <class T, class... A> void read(T&t, A&...a){read(t);read(a...);}
///////////////////////////////////////////////////////////////
int tr[MAXN];
int maxp;
inline void cha(int x, int v) {
	while(x<=maxp) {
		tr[x] = max(tr[x],v);
		x+=x&-x;
	}
}
inline int que(int x) {
	int ans=-INF;
	while(x>0) {
		ans = max(ans, tr[x]);
		x^=x&-x;
	}
	return ans;
}
///////////////////////////////////////////////////////////////
inline void cdqdiv(int l, int r) {
	int m=(l+r)>>1;
	if(l<m) cdqdiv(l,m);
	if(m+1<r) cdqdiv(m+1,r);
	int j=l;
	REPE(i,m+1,r) if(!op[i].v) {
		for(;j<=m && op[j].x<=op[i].x;j++) if(op[j].v) {
			cha(op[j].y, op[j].x+op[j].y);
		}
		int f=op[i].x+op[i].y-que(op[i].y);
		ans[op[i].id]=min(ans[op[i].id],f);
	}
	REP(i,l,j) if(op[i].v) {
		int y=op[i].y;
		for(;y<=maxp;y+=y&-y) tr[y]=-INF;
	}
	merge(op+l,op+m+1,op+m+1,op+r+1,tm);
	memcpy(op+l,tm,(char*)(op+r+1)-(char*)(op+l));
}
int main() {
	int n,m;read(n,m);
	opn=0;
	int ids=0; maxp=0;
	while(n--) {
		int x,y;read(x,y); x++,y++;
		maxp=max(maxp,y);
		op[opn]={.x=x,.y=y,.id=0,.v=true};
		opn++;
	}
	REP(i,0,m) {
		int v,x,y;read(v,x,y); x++,y++;
		maxp=max(maxp,y);
		op[opn]={.x=x,.y=y,.id=(v==1?0:ids++),.v=v==1};
		opn++;
	}
	memcpy(bk,op,(char*)(op+opn)-(char*)op);
	maxp++;
	memset(tr,-0x3f,(maxp+1)*sizeof(int));
	memset(ans,0x3f,ids*sizeof(int));
	cdqdiv(0,opn-1);
	
	memcpy(op,bk,(char*)(op+opn)-(char*)op);
	REP(i,0,opn) op[i].y=maxp-op[i].y;//避免树状树组查询到负数,在减法的时候可以抵消掉maxp
	cdqdiv(0,opn-1);
	
	memcpy(op,bk,(char*)(op+opn)-(char*)op);
	REP(i,0,opn) op[i].x=-op[i].x;
	cdqdiv(0,opn-1);
	
	memcpy(op,bk,(char*)(op+opn)-(char*)op);
	REP(i,0,opn) op[i].x=-op[i].x, op[i].y=maxp-op[i].y;
	cdqdiv(0,opn-1);
	
	REP(i,0,ids) printf("%d\n", ans[i]);
}

猜你喜欢

转载自www.cnblogs.com/sahdsg/p/12264075.html
今日推荐