HDU-4325 线段树+离散化
该题时间跨度太大,如果直接把时间建树的话显然内存不足,那么我们考虑到只有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; }