把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

【BZOJ2739】最远点(决策单调性)

点此看题面

  • 给定一个\(n\)个点的凸多边形,求到每个点距离最远的点。
  • \(n\le5\times10^5\)

决策单调性

我们直接把所有点给复制一份,就可以断环为链了。

考虑每个\(i\in[n+1,2n]\)的答案,它的合法决策区间是\([i-n+1,i-1]\)

这样一来,显然具有决策单调性。

直接分治求解即可。

代码:\(O(nlogn)\)

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 500000
using namespace std;
int n;struct P {int x,y;}p[2*N+5];
namespace FastIO
{
	#define FS 100000
	#define tc() (FA==FB&&(FB=(FA=FI)+fread(FI,1,FS,stdin),FA==FB)?EOF:*FA++)
	#define pc(c) (FC==FE&&(clear(),0),*FC++=c)
	#define D isdigit(oc=tc())
	int ff,OT;char oc,FI[FS],FO[FS],OS[FS],*FA=FI,*FB=FI,*FC=FO,*FE=FO+FS;
	I void clear() {fwrite(FO,1,FC-FO,stdout),FC=FO;}
	Tp I void read(Ty& x) {x=0,ff=1;W(!D) ff=oc^'-'?1:-1;W(x=(x<<3)+(x<<1)+(oc&15),D);x*=ff;}
	Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
	Tp I void writeln(Ty x) {W(OS[++OT]=x%10+48,x/=10);W(OT) pc(OS[OT--]);pc('\n');}
}using namespace FastIO;
int f[2*N+5];I void Solve(CI l,CI r,CI L,CI R)//分治决策单调性
{
	#define D(A,B) (1LL*(A.x-B.x)*(A.x-B.x)+1LL*(A.y-B.y)*(A.y-B.y))//距离
	if(l>r) return;RI i,mid=l+r>>1,o=max(L,mid-n+1);//左端点向mid-n+1取max
	for(i=o+1;i<=min(R,mid-1);++i) D(p[mid],p[i])>D(p[mid],p[o])&&(o=i);//右端点向mid-1取min
	f[mid]=o,Solve(l,mid-1,L,o),Solve(mid+1,r,o,R);//分治
}
int main()
{
	RI Tt,i;read(Tt);W(Tt--)
	{
		for(read(n),i=1;i<=n;++i) read(p[i].x,p[i].y),p[n+i]=p[i];//断环为链
		for(Solve(n+1,n<<1,1,n<<1),i=n+1;i<=(n<<1);++i) writeln(f[i]>n?f[i]-n:f[i]);//考虑每个i∈[n+1,2n]的答案
	}return clear(),0;
}
posted @ 2021-05-22 07:58  TheLostWeak  阅读(136)  评论(0编辑  收藏  举报