bzoj 2739 最远点——分治处理决策单调性

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2739

分治处理决策单调性的思想就是先找到一个询问,枚举所有可能的转移找到它的决策点,那么这个询问之前的询问的决策点就是在该决策点之前(含)的,这个询问之后的询问的决策点就是在该决策点之后(含)的。

但是有那个“(含)”,所以复杂度可能被卡?

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int rdn()
{
  int ret=0;bool fx=1;char ch=getchar();
  while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
  while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
  return fx?ret:-ret;
}
ll Sqr(int a){return (ll)a*a;}
const int N=5e5+5;
int n,x[N<<1],y[N<<1],ans[N];
bool cz(int bh,int u,int v)
{
  if(u<bh||u>bh+n)return false;//u<bh!!! u>.. not u>=...
  if(v<bh||v>bh+n)return true;
  ll a=Sqr(x[u]-x[bh])+Sqr(y[u]-y[bh]);
  ll b=Sqr(x[v]-x[bh])+Sqr(y[v]-y[bh]);
  return a>b;
}
void solve(int l,int r,int L,int R)
{
  if(l>r)return; int mid=l+r>>1,ret=L;
  for(int i=L+1;i<=R;i++)if(cz(mid,i,ret))ret=i;
  ans[mid]=ret;
  solve(l,mid-1,L,ret); solve(mid+1,r,ret,R);
}
int main()
{
  int T=rdn();
  while(T--)
    {
      n=rdn();
      for(int i=1;i<=n;i++)
    x[i]=x[i+n]=rdn(), y[i]=y[i+n]=rdn();
      solve(1,n,1,n<<1);
      for(int i=1;i<=n;i++)printf("%d\n",ans[i]>n?ans[i]-n:ans[i]);
    }
  return 0;
}

 

posted on 2019-04-02 18:16  Narh  阅读(122)  评论(0编辑  收藏  举报

导航