• HDU 4631 Sad Love Story (2013多校3 1011题 平面最近点对+爆搞)


    Sad Love Story

    Time Limit: 40000/20000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
    Total Submission(s): 16    Accepted Submission(s): 2


    Problem Description
    There's a really sad story.It could be about love or about money.But love will vanish and money will be corroded.These points will last forever.So this time it is about points on a plane.
    We have a plane that has no points at the start.
    And at the time i,we add point pi(xi, yi).There is n points in total.
    Every time after we add a point,we should output the square of the distance between the closest pair on the plane if there's more than one point on the plane.
    As there is still some love in the problem setter's heart.The data of this problem is randomly generated.
    To generate a sequence x1, x2, ..., xn,we let x0 = 0,and give you 3 parameters:A,B,C. Then xi = (xi-1 * A + B) mod C.
    The parameters are chosen randomly.
    To avoid large output,you simply need output the sum of all answer in one line.
     
    Input
    The first line contains integer T.denoting the number of the test cases.
    Then each T line contains 7 integers:n Ax Bx Cx Ay By Cy.
    Ax,Bx,Cx is the given parameters for x1, ..., xn.
    Ay,By,Cy is the given parameters for y1, ..., yn.
    T <= 10. 
    n <= 5 * 105.
    104 <= A,B,C <= 106.
     
    Output
    For each test cases,print the answer in a line.
     
    Sample Input
    2 5 765934 377744 216263 391530 669701 475509 5 349753 887257 417257 158120 699712 268352
     
    Sample Output
    8237503125 49959926940
    Hint
    If there are two points coincide,then the distance between the closest pair is simply 0.
     
    Source
     
    Recommend
    zhuyuanchen520
     

    这道题目的意思就是不断加入n个点。

    当点数>=2的时候,每加入一个点累加两点间最近距离的平方。

    按照给定的Ax,Bx,Cx,Ay,By,Cy,以及递推式可以产生n个点。

    The data of this problem is randomly generated.

    根据这句话,知道数据是随机产生,没有极端数据。

    所有首先n个点,做一下最近点对,复杂度O(nlogn)

    然后产生的最近点对,对于编号在最近点对后面的结果都可以累加了,同时后面的点也不需要了。

    所有去掉一部分点再次进行最近点对。

    这样不断重复,直到剩下一个点为止。

    /*
     *  Author:kuangbin
     *  1011.cpp
     */
    
    #include <stdio.h>
    #include <algorithm>
    #include <string.h>
    #include <iostream>
    #include <map>
    #include <vector>
    #include <queue>
    #include <set>
    #include <string>
    #include <math.h>
    using namespace std;
    const int MAXN = 500010;
    struct Point
    {
        int x,y;
        int id;
        int index;
        Point(int _x = 0,int _y = 0,int _index = 0)
        {
            x = _x;
            y = _y;
            index = _index;
        }
    };
    
    Point P[MAXN];
    
    
    long long dist(Point a,Point b)
    {
        return ((long long)(a.x-b.x)*(a.x-b.x) + (long long)(a.y-b.y)*(a.y-b.y));
    }
    Point p[MAXN];
    Point tmpt[MAXN];
    bool cmpxy(Point a,Point b)
    {
        if(a.x != b.x)return a.x < b.x;
        else return a.y < b.y;
    }
    bool cmpy(Point a,Point b)
    {
        return a.y < b.y;
    }
    pair<int,int> Closest_Pair(int left,int right)
    {
        long long d = (1LL<<50);
        if(left == right)return make_pair(left,right);
        if(left + 1 == right)
            return make_pair(left,right);
        int mid = (left+right)/2;
        pair<int,int>pr1 = Closest_Pair(left,mid);
        pair<int,int>pr2 = Closest_Pair(mid+1,right);
        long long d1,d2;
        if(pr1.first == pr1.second)
            d1 = (1LL<<50);
        else d1 = dist(p[pr1.first],p[pr1.second]);
    
        if(pr2.first == pr2.second)
            d2 = (1LL<<50);
        else d2 = dist(p[pr2.first],p[pr2.second]);
    
        pair<int,int>ans;
        if(d1 < d2)ans = pr1;
        else ans = pr2;
    
        d = min(d1,d2);
    
    
        int k = 0;
        for(int i = left;i <= right;i++)
        {
            if((long long)(p[mid].x - p[i].x)*(p[mid].x - p[i].x) <= d)
                tmpt[k++] = p[i];
        }
        sort(tmpt,tmpt+k,cmpy);
        for(int i = 0;i <k;i++)
        {
            for(int j = i+1;j < k && (long long)(tmpt[j].y - tmpt[i].y)*(tmpt[j].y - tmpt[i].y) < d;j++)
            {
                if(d > dist(tmpt[i],tmpt[j]))
                {
                    d = dist(tmpt[i],tmpt[j]);
                    ans = make_pair(tmpt[i].id,tmpt[j].id);
                }
            }
        }
        return ans;
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
       // freopen("out.txt","w",stdout);
        int T;
        int n,Ax,Ay,Bx,By,Cx,Cy;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d%d%d%d%d",&n,&Ax,&Bx,&Cx,&Ay,&By,&Cy);
            P[0] = Point(0,0,0);
            for(int i = 1;i <= n;i++)
            {
                long long x= ((long long)P[i-1].x*Ax + Bx)%Cx;
                long long y = ((long long)P[i-1].y*Ay + By)%Cy;
                P[i] = Point(x,y,i);
            }
            int end = n;
            long long ans = 0;
            while(end > 1)
            {
                for(int i = 0;i < end;i++)
                    p[i] = P[i+1];
                sort(p,p+end,cmpxy);
                for(int i = 0;i < end;i++)
                    p[i].id = i;
                pair<int,int>pr = Closest_Pair(0,end-1);
                int Max = max(p[pr.first].index,p[pr.second].index);
                ans += (long long)(end-Max+1)*dist(p[pr.first],p[pr.second]);
                end = Max-1;
            }
            printf("%I64d
    ",ans);
    
    
        }
        return 0;
    }
  • 相关阅读:
    BZOJ 2154 Crash的数字表格 莫比乌斯反演
    BZOJ 3529 SDOI2014 数表 莫比乌斯反演+树状数组
    bzoj 3527 [Zjoi2014]力
    【bzoj2194】快速傅立叶之二
    bzoj3160 万径人踪灭
    高精度乘法(FFT)
    【网络流24题】太空飞行计划
    奶牛通信
    关于点分治的理解
    0924解题报告
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3225602.html
Copyright © 2020-2023  润新知