• 最远点 决策单调性


    最远点

    描述:

    给你一个n个点的凸多边形,求离每一个点最远的点。

    题解:

    容易发现随着顺时针做每一个点其最远点也会顺时针旋转

    于是可以决策单调性

    因为从1的最远点开始转可以转过1

    所以将数组扩成两倍做

    //#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
    
    //#include <immintrin.h>
    //#include <emmintrin.h>
    #include <bits/stdc++.h>
    using namespace std;
    #define rep(i,h,t) for (int i=h;i<=t;i++)
    #define dep(i,t,h) for (int i=t;i>=h;i--)
    #define ll long long
    #define me(x) memset(x,0,sizeof(x))
    #define IL inline
    #define rint register int
    inline ll rd(){
        ll x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x;
    }
    char ss[1<<24],*A=ss,*B=ss;
    IL char gc()
    {
        return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;
    }
    template<class T>void maxa(T &x,T y)
    {
        if (y>x) x=y;
    }
    template<class T>void mina(T &x,T y)
    {
        if (y<x) x=y;
    }
    template<class T>void read(T &x)
    {
        int f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
        while(c=gc(),c>47&&c<58) x=x*10+(c^48); x*=f;
    }
    const int mo=1e9+7;
    ll fsp(int x,int y)
    {
        if (y==1) return x;
        ll ans=fsp(x,y/2);
        ans=ans*ans%mo;
        if (y%2==1) ans=ans*x%mo;
        return ans;
    }
    struct cp {
        ll x,y;
        cp operator +(cp B)
        {
            return (cp){x+B.x,y+B.y};
        }
        cp operator -(cp B)
        {
            return (cp){x-B.x,y-B.y};
        }
        ll operator *(cp B)
        {
            return x*B.y-y*B.x;
        }
        int half() { return y < 0 || (y == 0 && x < 0); }
    };
    const int N=2e5;
    struct re{
        ll a,b,id;
    }a[N];
    int n,f[N];
    ll d(re a,re b)   
    {   
      return 1ll*(a.a-b.a)*(a.a-b.a)+1ll*(a.b-b.b)*(a.b-b.b); 
    }
    bool pd(int now,int pos1,int pos2)
    {
        ll t1=d(a[now],a[pos1]),t2=d(a[now],a[pos2]);
        if (pos1<now||pos1>now+n)   t1=-t1;
        if (pos2<now||pos2>now+n)   t2=-t2;
        return t1!=t2?t1<t2:a[pos1].id>a[pos2].id;
    }
    void solve(int l,int r,int L,int R) 
    {
        if (l>r)    return;
        int mid=(l+r)>>1,Mid=L;
        for (int i=L;i<=R;i++)  if (pd(mid,Mid,i)) Mid=i;
        f[mid]=a[Mid].id;
        solve(l,mid-1,L,Mid);solve(mid+1,r,Mid,R);
    }
    int main()
    {
       ios::sync_with_stdio(false);
       int T=rd();
       while (T--)
       {
            n=rd();
            rep(i,1,n)
            {
                a[i].a=rd(); a[i].b=rd(); a[i].id=i;
                a[i+n]=a[i];
            }
            solve(1,n,1,n*2);
            rep(i,1,n) cout<<f[i]<<endl;
       }
       return 0;
    }
    View Code
  • 相关阅读:
    android 控件: xml 设置 Button 按下背景
    Hadoop: the definitive guide 第三版 拾遗 第四章
    二进制日志占满空间
    Unity3d学习笔记记录
    百度地图api---实现新建地图
    php简单浏览目录内容
    CRC校验的实现
    Android记录3--ExpandableListView使用+获取SIM卡状态信息
    Zookeeper Api(java)入门与应用(转)
    ZooKeeper程序员指南(转)
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/15011754.html
Copyright © 2020-2023  润新知