HDU 4631 Sad Love Story 计算几何 平面最近点对

给出n个点,计算从0开始每加入一个点最近点对点的距离的平方,累加答案

思路:用模板直接暴力复杂度太高,考虑平衡树来支持插入操作(set)

由于此题只涉及点的操作,无需写大量计算几何模板,直接利用分治求最近点对,加入以后check最近的即可

#include<iostream>
#include<unordered_map>
#include<algorithm>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<deque>
#include<stack>
#include<sstream>
#include <cstdlib>
#include<cstdio>
#include<random>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define equals(a,b) (fabs(a-b)<eps)
#define MOD 100000007
std::mt19937 rnd(233);
//#define rnd() rand()%1000
const int maxn = 5e5+5 ;
const double PI = acos(-1.0);
typedef long long ll;
using namespace std;

struct Point {
    ll x;
    ll y;
    Point(ll x = 0, ll y = 0) :x(x), y(y) {}
    friend bool operator < (const Point& a, const Point& b) {
        if (a.x != b.x) return a.x < b.x;
        else return a.y < b.y;
    }
};

set<Point> v;

int main() {
    int T;
    int n, a1, b1, c1, a2, b2, c2;
    scanf("%d", &T);
    while (T--) {
        v.clear();
        scanf("%d%d%d%d%d%d%d", &n, &a1, &b1, &c1, &a2, &b2, &c2);
        ll x, y, sum, mids;
        x = y = sum = 0;
        mids = (1ll<<60)-1;
        for (int i = 0; i < n; i++) {
            x = (x * a1 + b1) % c1;
            y = (y * a2 + b2) % c2;
            Point p;
            p.x = x, p.y = y;
            if (!v.count(p)) {
                if (i > 0) {
                    auto it = v.lower_bound(p);
                    for (auto e = it; e != v.end(); e++) {
                        int next_x = e->x - p.x;
                        if (next_x * next_x > mids) break;
                        int next_y = e->y - p.y;
                        ll dis = (ll)next_x * next_x + (ll)next_y * next_y;
                        mids = min(mids, dis);
                    }
                    for (auto e = it; e != v.begin(); ) {
                        e--;
                        int next_x = e->x - p.x;
                        if (next_x * next_x > mids) break;
                        int next_y = e->y - p.y;
                        ll dis = (ll)next_x * next_x + (ll)next_y * next_y;
                        mids = min(dis, mids);
                    }
                    sum += mids;
                }
                v.insert(Point(x, y));
            }
            else break;
        }
        printf("%lld\n", sum);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/hznumqf/p/12607678.html
sad
今日推荐