HDU4325 线段树+离散化

该题时间跨度太大,如果直接把时间建树的话显然内存不足,那么我们考虑到只有10^5朵花,于是要采取离散化,但是如果只是离散化花朵的时间的话,那么当我们去查询某个时间的时候,这个时间点在线段树里面的信息的不存在的,于是也就得不到正确的答案,因此我们要离散化花朵和询问的所有时间,这样信息就完备了。

代码如下:

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;

int N, M, ti[300005], cnt, Q[100005];

struct Flower
{
    int s, e;    
}f[100005];

map<int,int>mp;

struct Node
{
    int l, r, lazy;    
}e[1200005];

void build(int p, int l, int r)
{
    e[p].l = l, e[p].r = r;
    e[p].lazy = 0;
    if (l != r) {
        int mid = (l + r) >> 1;
        build(p<<1, l, mid);
        build(p<<1|1, mid+1, r);
    }
}

void push_down(int p)
{
    if (e[p].lazy) {
        e[p<<1].lazy += e[p].lazy;
        e[p<<1|1].lazy += e[p].lazy;
        e[p].lazy = 0;
    }    
}

void modify(int p, int l, int r)
{
    if (l == e[p].l && r == e[p].r) {
        e[p].lazy += 1;    
    }
    else {
        push_down(p);
        int mid = (e[p].l + e[p].r) >> 1;
        if (r <= mid) {
            modify(p<<1, l, r);
        }
        else if (l > mid) {
            modify(p<<1|1, l, r);    
        }
        else {
            modify(p<<1, l, mid);
            modify(p<<1|1, mid+1, r);    
        }
    } 
}

int query(int p, int pos)
{
    if (e[p].l == e[p].r) {
        return e[p].lazy;    
    }
    else {
        push_down(p);
        int mid = (e[p].l + e[p].r) >> 1;
        if (pos <= mid) {
            return query(p<<1, pos);    
        }    
        else {
            return query(p<<1|1, pos);    
        }
    }
}

int main()
{
    int T, ca = 0;
    scanf("%d", &T);
    while (T--) {
        cnt = -1;
        mp.clear();
        scanf("%d %d", &N, &M);
        for (int i = 1; i <= N; ++i) {
            scanf("%d %d", &f[i].s, &f[i].e);    
            ti[++cnt] = f[i].s, ti[++cnt] = f[i].e;
        }
        for (int i = 1; i <= M; ++i) {
            scanf("%d", &Q[i]);
            ti[++cnt] = Q[i];
        }
        sort(ti, ti+cnt+1);
        cnt = unique(ti, ti+cnt+1) - ti;
        for (int i = 0; i < cnt; ++i) {
            mp[ti[i]] = i;
        }
        build(1, 0, cnt-1);
        for (int i = 1; i <= N; ++i) {
            modify(1, mp[f[i].s], mp[f[i].e]);
        }
        printf("Case #%d:\n", ++ca);
        for (int i = 1; i <= M; ++i) {
            printf("%d\n", query(1, mp[Q[i]]));
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Lyush/p/2617907.html