[Gym-101482] G-Gathering (ensemble de trois points de trois points + somme des préfixes)

Titre

Le plan bidimensionnel donne n points intégraux, trouvez un point intégral (x, y) de sorte que la distance de Manhattan de ce point intégral aux n autres points soit la plus petite, et il doit rencontrer la distance de Manhattan de chaque point à ceci (x, y) Pas plus de d.
N ≤ 1 e 5, 0 ≤ xi, yi ≤ 1 e 9, 0 ≤ d ≤ 2 e 9 n \ le 1e5, 0 \ le x_i, y_i \ le 1e9, 0 \ le d \ le 2e9n1 e 5 ,0XJe,etJe1 e 9 ,02 e 9

Idées de résolution de problèmes

S'il n'y a pas de limite de "la distance de Manhattan de chaque point à ceci (x, y) ne dépasse pas d.", Alors un accès facile (médiane de x, médiane de y) est le meilleur point.
Compte tenu de la restriction, nous constatons que chaque Chaque point a une zone facultative en forme de losange. L'intersection des n zones facultatives en forme de losange est la zone que nous pouvons choisir. Cette zone peut en fait être vue comme une zone encadrée par 4 lignes droites, puis nous maintenons ces 4 lignes droites La zone légale peut être obtenue.
Notez que lorsque x est déterminé, la fonction de la réponse par rapport à y est une fonction concave. De même, lorsque x change, y est utilisé comme position de sélection optimale pour chaque x, alors la réponse est une fonction de x C'est aussi une fonction concave, donc l'ensemble de trois points de trois points est fait.
Lorsque vous recherchez la réponse, vous pouvez utiliser la somme de deux points + préfixe pour obtenir rapidement la somme des distances de Manhattan de n points au point spécifié.

#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define lowbit(x) ((x)&(-(x)))
#define mid ((l+r)>>1)
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
#define fors(i, a, b) for(int i = (a); i < (b); ++i)
#define P pair<int,int>
using namespace std;
const int maxn = 1e5 + 50;
const ll inf = 0x3f3f3f3f3f3f3f3f;
int n;
ll xsum[maxn], ysum[maxn];
ll x[maxn], y[maxn];
ll d;
ll L = -inf, R = inf;//x-y
ll D = -inf, U = inf;//x+y
ll f(ll a, ll b[], ll c[]){
    
    
    if(a > b[n]){
    
    
        return (ll)n*a - c[n];
    }else if(a < b[0]){
    
    
        return c[n]-n*a;
    }else{
    
    
        int p = lower_bound(b+1, b+1+n, a)-b;
        return (c[n] - c[p-1] - (ll)(n-p+1)*a) + (ll)(p-1)*a - c[p-1];
    }
}
bool in(int x, int y){
    
    
    ll t1 = x-y;
    ll t2 = x+y;
    //cout<<"L:"<<L<<" R:"<<R<<" D:"<<D<<" U:"<<U<<endl;
    return L<=t1 && t1 <= R && D <= t2 && t2 <= U;
}
ll sol(ll a){
    
    
    ll l = max(a-R, D-a);
    ll r = min(a-L, U-a);
    if(r < l) return inf;
    ll ans = inf;
    while(r-l >= 3){
    
    
        ll lmid = l + (r-l)/3;
        ll rmid = r - (r-l)/3;
        ll la = f(lmid, y, ysum), ra = f(rmid, y, ysum);
        if(la >= ra) ans = min(ra, ans), l = lmid;
        else ans = min(ans, la), r = rmid;
    }
    while(l <= r) ans = min(ans, f(l, y, ysum)), l++;
    return ans;
}
int main()
{
    
    
    scanf("%d", &n);
    fors(i, 1, n+1) {
    
    
        scanf("%lld%lld", &x[i], &y[i]);
    }
    cin>>d;
    fors(i, 1, n+1){
    
    
        L = max(L, x[i] - y[i]-d);
        R = min(R, x[i] - y[i]+d);
        D = max(D, x[i] + y[i]-d);
        U = min(U, x[i] + y[i]+d);
    }
    sort(x+1, x+1+n); sort(y+1, y+1+n);
    fors(i, 1, n+1) xsum[i] = xsum[i-1] + x[i], ysum[i] = ysum[i-1] + y[i];
    if(in(x[n/2], y[n/2])){
    
    
        cout<<f(x[(n+1)/2], x, xsum)+f(y[(n+1)/2], y, ysum)<<endl;
    }else if(U < D || R < L){
    
    
        printf("impossible\n");
    }else {
    
    
        ll ans = inf;
        ll l = (D+L+1)/2;
        ll r = (R+U)/2;
        //cout<<"l:"<<l<<" r:"<<r<<endl;
        while(r-l >= 3){
    
    
            ll lmid = l + (r-l)/3;
            ll rmid = r - (r-l)/3;
            ll la = sol(lmid) + f(lmid, x, xsum);
            ll ra = sol(rmid) + f(rmid, x, xsum);
            if(la >= ra) ans = min(ans, ra), l = lmid;
            else ans = min(ans, la), r = rmid;
        }
        while(l <= r) ans = min(ans, sol(l)+f(l, x, xsum)), l++;
        cout<<ans<<endl;
    }
}
/*
5
3 1
4 1
5 9
2 6
5 3
4

*/

Je suppose que tu aimes

Origine blog.csdn.net/qq_43202683/article/details/105631998
conseillé
Classement