HDU 4631 - Sad Love Story(最近點對)

題意:給出A、B、C,按照給出的公式推出每一個點,添加每一個點時,求出相應的最短距離,所有最短距離加和

因爲是隨機點,不可能有邊界數據,所以可以爆搞

每次找(0,R-1)區間的最近點對(R爲上一個最近點對裏面編號最大的),然後加上R到N裏面所有的距離(相乘即可)

這題搞出來的。。。應該不是什麼正規解法。。。跑了19015ms。。。還是太水了

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
#define LL long long
const int maxn = 500050;

typedef struct Point
{
    int Id;
    int No;
    LL x,y;
    Point(LL _x=0,LL _y=0,int _Id=0):x(_x),y(_y),Id(_Id){}
    bool operator < (const Point &a) const{
        return x<a.x || (x==a.x && y<a.y);
    }
}Point;

typedef struct Pair
{
    LL dis;
    int na;
    int nb;
    bool operator < (const Pair &a) const{
        return dis<a.dis ;
    }
} Pair;
int n;

Point P[maxn];
Point p[maxn],py[maxn];

int cmpy(Point a, Point b)
{
    return a.y < b.y;
}

Pair dis(Point a, Point b)
{
    Pair p;
    p.dis=(a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);
    p.na=a.No;
    p.nb=b.No;
    return p;
}

Pair closest( int l, int r )
{
    if( l+1 == r )
        return dis( p[l], p[r]) ;
    if( l+2 == r )
        return min( dis(p[l],p[l+1]), min( dis(p[l+1],p[r]), dis(p[l],p[r]) ) ) ;
    int mid = (l+r)/2 ;
    Pair pr = min( closest(l,mid), closest(mid+1,r) ) ;
    int i, j, cnt=0 ;
    for( i=l; i<=r; i++ ){
        if( p[i].x >= p[mid].x-pr.dis && p[i].x <= p[mid].x+pr.dis ){
            py[cnt++] = p[i] ;
        }
    }
    sort( py, py+cnt, cmpy ) ;
    for( i=0; i<cnt; i++ ){
        for( j=i+1; j<cnt && (py[j].y-py[i].y)*(py[j].y-py[i].y)<pr.dis; j++ ){
            // py數組中的點是按照y座標升序的
            pr = min( pr, dis(py[i],py[j]) ) ;
        }
    }
    return pr ;
}

int main()
{
    int T,n;
    LL ax,ay,bx,by,cx,cy;

    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&ax,&bx,&cx,&ay,&by,&cy);
        P[0]=Point(0,0,0);
        for(int i=1;i<=n;i++)
        {
            LL x = (P[i-1].x*ax + bx)%cx;
            LL y = (P[i-1].y*ay + by)%cy;
            P[i] = Point(x,y,i);
        }
        int end=n;
        LL ans=0;
        while(end>1)
        {
            for(int i = 0;i < end;i++)
                p[i] = P[i+1];
            sort(p, p+end);
            for(int i = 0;i < end;i++)
                p[i].No = i;
            Pair pr = closest(0,end-1);
            int Max = max(p[pr.na].Id,p[pr.nb].Id);
            ans += (end-Max+1)*dis(p[pr.na],p[pr.nb]).dis;
            end = Max-1;
        }
        printf("%I64d\n",ans);

    }

    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章