Cod sursa(job #1988827)

Utilizator mariusn01Marius Nicoli mariusn01 Data 4 iunie 2017 20:06:10
Problema Gropi Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.61 kb
#include <fstream>
#include <algorithm>
#define DIM 100010
#define x second
#define y first

using namespace std;

struct secv {
    int st;
    int dr;
    int tip;
};

secv s[DIM];
pair<int, int> v[DIM];
int c, n, m, i, j, X1, X2, Y1, Y2, L, k, st, dr, mid, in1, in2, z1, z2;
long long pls;
int A[DIM], B[DIM], a, b;
ifstream fin ("gropi.in");
ofstream fout("gropi.out");

int cautaInainte(int a[], int n, int x) {
    int st = 1, dr = n;
    while (st <= dr) {
        int mid = (st + dr)/2;
        if (x > a[mid])
            st = mid+1;
        else
            dr = mid-1;
    }
    return dr;

}

int main () {

    fin>>c>>n;
    for (i=1;i<=n;i++)
        fin>>v[i].x>>v[i].y;

    sort(v+1, v+n+1);

    k = 0;
    for (i=1;i<=n;i++)
        if (v[i].y != v[k].y) {
            v[++k] = v[i];
        } else {
            if (v[i].x != v[k].x)
                k--;
        }
    n = k;

    k = 0;

    if (n != 0) {
        L = 1;

        if (v[1].x == 1)
            A[++a] = v[1].y;
        else
            B[++b] = v[1].y;

        for (i=2;i<=n;i++) {

            if (v[i].x == 1)
                A[++a] = v[1].y;
            else
                B[++b] = v[1].y;


            if (v[i].x == v[i-1].x)
                L++;
            else {
                k++;
                s[k].st = v[i-1-L+1].y;
                s[k].dr = v[i-1].y;
                s[k].tip = v[i-1].x;
                L = 1;
            }
        }
        k++;
        s[k].st = v[i-1-L+1].y;
        s[k].dr = v[i-1].y;
        s[k].tip = v[i-1].x;

    }

    fin>>m;
    for (;m--;) {
        fin>>X1>>Y1>>X2>>Y2;

        if (n == 0) {
            if (X1 == X2)
                fout<<Y2-Y1+1<<"\n";
            else
                fout<<Y2-Y1+2<<"\n";
            continue;
        }

        if ((Y1 > Y2) || ( (Y1 == Y2) && (X1 > X2) )) {
            swap(X1, X2);
            swap(Y1, Y2);
        }

        /// caut zona in care se afla Y1 sau prima de dupa
        st = 1;
        dr = k;
        while (st <= dr) {
            mid = (st + dr)/2;
            if (Y1 >= s[mid].st && Y1 <= s[mid].dr)
                break;
            if (Y1 > s[mid].dr)
                st = mid+1;
            else
                dr = mid-1;
        }

        if(st <= dr) {
            in1 = 1;
            z1 = mid;
        } else {
            in1 = 0;
            z1 = st;
        }

        /// caut zona in care se afla Y2 sau prima de inainte
        st = 1;
        dr = k;
        while (st <= dr) {
            mid = (st + dr)/2;
            if (Y2 >= s[mid].st && Y2 <= s[mid].dr)
                break;
            if (Y2 > s[mid].dr)
                st = mid+1;
            else
                dr = mid-1;
        }
        if (st <= dr) {
            in2 = 1;
            z2 = mid;
        } else {
            in2 = 0;
            z2 = dr;
        }
        /// ambele capetele sunt in zone
        if (in1 && in2) {
            if (z1 == z2) {
                if (X1 != X2) {
                    fout<<Y2-Y1+1+1<<"\n";
                } else {
                    if (X1 != s[z1].tip)
                        fout<<Y2-Y1+1<<"\n";
                    else {
                        if ((X1 == 1) && (cautaInainte(A, a, X1) == cautaInainte(A, a, X2)))
                            fout<<Y2-Y1+1<<"\n";
                        else
                            if ((X1 == 2) && (cautaInainte(B, b, X1) == cautaInainte(B, b, X2)))
                                fout<<Y2-Y1+1<<"\n";
                            else
                                fout<<Y2-Y1+1+2<<"\n";
                    }
                }
            } else {
                pls = z2 - z1;
                if (s[z1].tip == X1)
                    pls++;
                if (s[z2].tip == X2)
                    pls++;
                fout<<Y2-Y1+1+pls<<"\n";
            }
            continue;
        }
        if (!in1 && !in2) {
            if (z1 - 1 == z2) {
                if (X1 == X2)
                    fout<<Y2-Y1+1<<"\n";
                else
                    fout<<Y2-Y1+2<<"\n";
            } else {
                pls = z2 - z1;
                if (X1 == s[z1].tip)
                    pls++;
                if (X2 == s[z2].tip)
                    pls++;
                fout<<Y2-Y1+1+pls<<"\n";
            }
            continue;
        }

        pls = z2 - z1;
        if (X1 == s[z1].tip)
            pls++;
        if (X2 == s[z2].tip)
            pls++;
        fout<<Y2-Y1+1+pls<<"\n";

    }

    return 0;
}