Cod sursa(job #1771176)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 5 octombrie 2016 12:26:49
Problema Metrou4 Scor 0
Compilator cpp Status done
Runda Arhiva ICPC Marime 3.33 kb
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <utility>

#define x first
#define y second
#define mycreation std::pair <int, int>

#define MAXN 150000
#define MAXP 530000

int n, m, left, right, sef, poz, rez, val;
int t[MAXN+1], a[MAXN+1], ind[MAXN+1];
int aint[MAXP], cine[MAXP];
mycreation v[MAXN+1];

struct godscreation{
    int x, y, z;
    bool operator<(const godscreation &u) const{
        return z<u.z;
    }
}sol[8*MAXN];

inline int myabs(int x){
    if(x<0) return -x;
    else return x;
}

inline void rot90(){
    int x, y;
    for(int i=1; i<=n; i++){
        x=v[i].x;
        y=v[i].y;
        v[i].x=-y;
        v[i].y=x;
    }
}

inline void reflect(){
    for(int i=1; i<=n; i++)
        v[i].x*=-1;
}

int find(int x){
    if(x==t[x]) return x;
    else return t[x]=find(t[x]);
}

bool cmp(const int &a, const int &b){
    return v[a]<v[b];
}

inline int cautbin(int x){
    int rez=0;
    for(int pas=1<<29; pas; pas>>=1)
        if((rez+pas<=n)&&(a[rez+pas]<=x))
            rez+=pas;
    return rez;
}

void update(int p, int st, int dr){
    if(st==dr){
        aint[p]=val;
        cine[p]=sef;
    }else{
        int m=(st+dr)/2;
        if(poz<=m) update(2*p, st, m);
        else update(2*p+1, m+1, dr);
        aint[p]=aint[2*p];
        cine[p]=cine[2*p];
        if((cine[p]==0)||((cine[2*p+1]!=0)&&(aint[2*p+1]<aint[p]))){
            aint[p]=aint[2*p+1];
            cine[p]=cine[2*p+1];
        }
    }
}

void query(int p, int st, int dr){
    if((left<=st)&&(dr<=right)){
        if((sef==0)||((cine[p]!=0)&&(aint[p]<rez))){
            rez=aint[p];
            sef=cine[p];
        }
    }else{
        int m=(st+dr)/2;
        if(left<=m) query(2*p, st, m);
        if(m+1<=right) query(2*p+1, m+1, dr);
    }
}

inline void muchii(){
    for(int i=1; i<=n; i++)
        ind[i]=i;
    std::sort(ind+1, ind+n+1, cmp);
    for(int i=1; i<=n; i++)
        a[i]=v[i].x-v[i].y;
    std::sort(a+1, a+n+1);
    memset(cine, 0, sizeof cine);
    for(int i=n; i>0; i--){
        poz=cautbin(v[ind[i]].x-v[ind[i]].y);
        rez=0;
        sef=0;
        left=1;
        right=poz;
        query(1, 1, n);
        if(sef!=0){
            sol[m].x=ind[i];
            sol[m].y=sef;
            sol[m].z=rez-v[ind[i]].x-v[ind[i]].y;
            m++;
        }
        val=v[ind[i]].x+v[ind[i]].y;
        sef=ind[i];
        update(1, 1, n);
    }
}

int main(){
    int h;
    long long ans;
    FILE *fin, *fout;
    fin=fopen("metrou4.in", "r");
    fout=fopen("metrou4.out", "w");
    fscanf(fin, "%d", &h);
    for(; h; h--){
        m=0;
        fscanf(fin, "%d", &n);
        for(int i=1; i<=n; i++)
            fscanf(fin, "%d%d", &v[i].x, &v[i].y);
        for(int i=0; i<2; i++){
            for(int j=0; j<4; j++){
                muchii();
                rot90();
            }
            reflect();
        }
        std::sort(sol, sol+m);
        for(int i=1; i<=n; i++)
            t[i]=i;
        ans=0;
        for(int i=0; i<m; i++){
            if(find(sol[i].x)!=find(sol[i].y)){
                ans+=sol[i].z;
                t[find(sol[i].x)]=find(sol[i].y);
            }
        }
        fprintf(fout, "%lld\n", ans);
    }
    fclose(fin);
    fclose(fout);
    return 0;
}