루오 구 P2163 [SHOI2007] 종묘 트러블 (오프라인 정렬 펜윅 트리 문제를 해결하기 위해, 부분 입체 순서)

P2163 [SHOI2007] 종묘 트러블

제목 설명

옛날 옛적에, 먼 대륙의 아름다운 나라가있다. 이 아름다운 나라는 왕이 자신의 왕실 정원에 이국적인 식물의 다양한 심은 원예 애호가이다 판결했다.

"...... 최근에 우리는 육 육각형으로 화단을 넣으면 그때, 문제에 대해 생각했다"왕 정원에서 산책 어느 날, 신중, 그는 정원사가 말했다 요청

"본질적으로는 깊이 우선 탐색, 폐하이다 그래서,"왕에게 정원사 깊이 절.

"아 ... 나는 그것이 매우 욕심 사과 나무입니다 히드라라는 괴물이 들었다 ......"

"예, 분명히이 이르면 우리는 폐하의 신비를 발견했다 (4002)에서 N 위안으로, 고전적인 동적 프로그래밍 문제입니다."

"젠장, 당신은 무엇을 백업하는?"

"폐하, 진정 나는 또한 아! 예방 조치입니다, 우리의 라인과 OI는 종종 알수없는 주제에 대해 질문 건조"왕의 위엄이 아팠다,이 참을 수있다.

그것은 문제가 일반적으로 왕이 마침내 자신의 힘 소비 휠 전투에가는 정원사를 이길 것 같다 : 잠시 동안, 내 정원에서 모든 나무는 정수 좌표로 표현 될 수있다 "젊은 남자, I 기사는 즉시 대답 할 수없는 경우, 당신이 그것을 떠날 준비가되어, 매트릭스 내에서 당신에게 나무의 수를 물어 교대로 할 것이다! "그 왕은 화가 나서 처음으로 이동합니다.

이것은 다음 차례 정원사 어이, 그는 이러한 문제를 준비하지 않았다. 다행히, "보존 정원사를위한 전국 연합 '의 대통령으로 - 당신은 그의 마지막 밀짚 수 있습니다.

입력 형식

첫 번째 라인은 두 정수 N, m (0≤n≤500000,1≤m≤500000)을 갖는다. N은 왕실 정원의 나무의 총 개수, m은 요청 기사의 수를 나타냅니다 나타냅니다.

N 라인 다음 파일, 각 라인은 두 정수 XI 이순신을 가지고 난 트리 (0≤xi, yi≤10000000)의 좌표를 나타낸다.

파일의 M 마지막 행은 각 행은, 네 개의 정수 j까지, BJ, CJ, DJ를 갖는다 (AJ, BJ)에 Q 사각형 하부 좌측 좌표이고 j 번째 질문을 나타낸다 (CJ는 DJ)의 오른쪽은 조정합니다.

출력 형식

총 출력 m 라인, 왕 (AJ, BJ)와 (CJ, DJ)에 대한 답 정수, 각각이 얼마나 많은 나무의 사각형 경계입니다.

샘플 입출력

입력 # 1 사본

3 1
0 0 
0 1
1 0
0 0 1 1

출력 # 1 사본

3

아이디어 :

포인트의 수의 문제를 해결하기 위해 치수 부분은 직사각형의 2 차원 평면을 포함한다.

크기 :

{

x 축은

Y 축

액션 유형

}

우리는 처음에 n 개의 점의 좌표를 추가하는 작업으로 주어진

다음 m에 귀하의 질문.

따라서 X 및 Y는 동일 점선 우선 때 같은 X, Y 오름차순으로하는 방법.

넷 프리픽스 (0,0)에 문의하는 이차원 자연 얻어진 좌측 하단 문의 축적 기여 하위 노드.

정렬 후, 젊고 아름다운 여자의 대답을 유지하기 위해 배열을 사용합니다.

코드 :

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
#define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
#define du2(a,b) scanf("%d %d",&(a),&(b))
#define du1(a) scanf("%d",&(a));
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {a %= MOD; if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}

inline void getInt(int *p);
const int maxn = 3000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/

ll tree[maxn];
int lowbit(int x)
{
    return -x & x;
}
ll ask(int x)
{
    ll res = 0ll;
    while (x) {
        res += tree[x];
        x -= lowbit(x);
    }
    return res;
}
int my=0;
void add(int x, ll val)
{
    while (x < my) {
        tree[x] += val;
        x += lowbit(x);
    }
}
pii a[maxn];
pii b[maxn];
pii c[maxn];
int n, m;
std::vector<int> vx,vy;
struct node {
    int op;
    int x, y;
    int k;
    int id;
    node() {}
    node(int opp, int xx, int yy, int kk, int idd)
    {
        op = opp;
        x = xx;
        y = yy;
        k = kk;
        id = idd;
    }
} info[maxn];
int ans[maxn];
bool cmp(node aa, node bb)
{
    if (aa.x != bb.x) {
        return aa.x < bb.x;
    } else if (aa.op != bb.op) {
        return aa.op < bb.op;
    } else {
        return aa.y < bb.y;
    }
}
int main()
{
    //freopen("D:\\code\\text\\input.txt","r",stdin);
    //freopen("D:\\code\\text\\output.txt","w",stdout);
    gbtb;
    cin >> n >> m;
    repd(i, 1, n) {
        cin >> a[i].fi >> a[i].se;
        vx.push_back(a[i].fi);
        vy.push_back(a[i].se);
    }
    repd(i, 1, m) {
        cin >> b[i].fi >> b[i].se >> c[i].fi >> c[i].se;
        vx.push_back(b[i].fi);
        vy.push_back(b[i].se);
        vx.push_back(c[i].fi);
        vy.push_back(c[i].se);
        vy.push_back(b[i].se - 1);
        vx.push_back(b[i].fi - 1);
    }
    sort(ALL(vx));
    sort(ALL(vy));
    vx.erase(unique(ALL(vx)),vx.end());
    vy.erase(unique(ALL(vy)),vy.end());
    my=sz(vy)+10;
    int cnt = 0;
    int dx, dy;
    repd(i, 1, n) {
        ++cnt;
        dx = lower_bound(ALL(vx), a[i].fi) - vx.begin() + 1;
        dy = lower_bound(ALL(vy), a[i].se) - vy.begin() + 1;
        info[cnt] = node(0, dx, dy, 0, 0);
    }
    repd(i, 1, m) {
        ++cnt;
        dx = lower_bound(ALL(vx), c[i].fi) - vx.begin() + 1;
        dy = lower_bound(ALL(vy), c[i].se) - vy.begin() + 1;
        info[cnt] = node(1, dx, dy, 1, i);

        ++cnt;
        dx = lower_bound(ALL(vx), c[i].fi) - vx.begin() + 1;
        dy = lower_bound(ALL(vy), b[i].se - 1) - vy.begin() + 1;
        info[cnt] = node(1, dx, dy, -1, i);

        ++cnt;
        dx = lower_bound(ALL(vx), b[i].fi - 1) - vx.begin() + 1;
        dy = lower_bound(ALL(vy), c[i].se) - vy.begin() + 1;
        info[cnt] = node(1, dx, dy, -1, i);

        ++cnt;
        dx = lower_bound(ALL(vx), b[i].fi-1) - vx.begin() + 1;
        dy = lower_bound(ALL(vy), b[i].se-1) - vy.begin() + 1;
        info[cnt] = node(1, dx, dy, 1, i);

    }
    sort(info + 1, info + 1 + cnt, cmp);
    repd(i, 1, cnt) {
        if (!info[i].op) {
            add(info[i].y, 1);
        } else {
            ans[info[i].id] += info[i].k * ask(info[i].y);
        }
    }
    repd(i, 1, m) {
        printf("%d\n", ans[i] );
    }
    return 0;
}

inline void getInt(int *p)
{
    char ch;
    do {
        ch = getchar();
    } while (ch == ' ' || ch == '\n');
    if (ch == '-') {
        *p = -(getchar() - '0');
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 - ch + '0';
        }
    } else {
        *p = ch - '0';
        while ((ch = getchar()) >= '0' && ch <= '9') {
            *p = *p * 10 + ch - '0';
        }
    }
}



추천

출처www.cnblogs.com/qieqiemin/p/11594591.html