Cod sursa(job #2634933)

Utilizator andreiomd1Onut Andrei andreiomd1 Data 12 iulie 2020 18:58:59
Problema Ograzi Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.58 kb
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

const int NMAX = 5e4 + 5, MMAX = 1e5 + 5, VMAX = 1e6 + 5;
const int BEGIN = -1, QUERY = 0, END = 1;
const int INF = 1e9;

int N, M, W, H, Max = -INF;
int MIN = INF, MAX = -INF;

struct Event
{
    short int Type;

    int Y1, Y2;
};

vector < Event > V[VMAX];

namespace InParser
{
static const int BSIZE = (1 << 16);

static int pos = BSIZE - 1;
static char buff[BSIZE];

static inline char Char ()
{
    ++pos;

    if(pos == BSIZE)
    {
        pos = 0;

        int n = fread(buff, 1, BSIZE, stdin);

        if(n != BSIZE)
            for(int i = n; i < BSIZE; ++i)
                buff[i] = 0;
    }

    return buff[pos];
}

inline int Int ()
{
    int ans = 0, sign = 1;

    for( ; ; )
    {
        char Ch = Char();

        if(Ch == '-')
        {
            sign = -1;

            break;
        }

        if(Ch >= '0' && Ch <= '9')
        {
            ans = (int)(Ch - '0');

            break;
        }
    }

    for( ; ; )
    {
        char Ch = Char();

        if(Ch >= '0' && Ch <= '9')
            ans = ans * 10 + (int)(Ch - '0');
        else
            break;
    }

    return (ans * sign);
}
};

class FenwickTree
{
    int a[VMAX];

private:
    static inline int UB (int X)
    {
        return (X & (-X));
    }

    inline void Update (int pos, int Val)
    {
        for(int i = pos; i <= Max; i += UB(i))
            a[i] += Val;

        return;
    }

public:
    inline void Go (int Left, int Right, int Val)
    {
        Update(Left, Val);
        Update(Right + 1, -Val);

        return;
    }

    inline int Query (int pos)
    {
        int ans = 0;

        for(int i = pos; i >= 1; i -= UB(i))
            ans += a[i];

        return ans;
    }
} AIB;

static inline void Read ()
{
    ios_base :: sync_with_stdio(false);
    cin.tie(nullptr);

    freopen("ograzi.in", "r", stdin);
    freopen("ograzi.out", "w", stdout);

    N = InParser :: Int(), M = InParser :: Int();
    W = InParser :: Int(), H = InParser :: Int();

    for(int i = 1; i <= N; ++i)
    {
        int X1 = InParser :: Int(), Y1 = InParser :: Int();
        int X2 = X1 + W, Y2 = Y1 + H;

        Max = max(Max, (Y2 + 1));

        MIN = min(MIN, X1);
        MAX = max(MAX, X2);

        V[X1].push_back({BEGIN, Y1, Y2});
        V[X2].push_back({END, Y1, Y2});
    }

    for(int i = 1; i <= M; ++i)
    {
        int X = InParser :: Int(), Y1 = InParser :: Int();

        Max = max(Max, (Y1 + 1));

        MIN = min(MIN, X);
        MAX = max(MAX, X);

        V[X].push_back({QUERY, Y1, Y1});
    }

    return;
}

auto cmp = [] (Event A, Event B)
{
    if(A.Type < B.Type)
        return 1;

    return 0;
};

static inline void Solve ()
{
    int ans = 0;

    for(int X = MIN; X <= MAX; ++X)
        if(!V[X].empty())
        {
            sort(V[X].begin(), V[X].end(), cmp);

            for(auto it : V[X])
                if(it.Type == BEGIN)
                    AIB.Go(it.Y1, it.Y2, 1);
                else if(it.Type == END)
                {
                    if(X == MAX)
                        break;

                    AIB.Go(it.Y1, it.Y2, -1);
                }
                else
                {
                    if(AIB.Query(it.Y1))
                        ++ans;
                }
        }

    printf("%d\n", ans);

    return;
}

int main()
{
    Read();

    Solve();

    return 0;
}