题意:给出一些花开花落的时间,问某个时间花开的有几朵
分析:这题有好几种做法,正解应该是离散化坐标后用线段树成端更新和单点询问。还有排序后二分查找询问点之前总花开数和总花凋谢数,作差是当前花开的数量,放张图易理解:
还有一种做法用尺取法的思想,对暴力方法优化,对询问点排序后再扫描一遍,花开+1,花谢-1。详细看代码。
收获:一题收获很多:1. 降低复杂度可以用二分 2. 线段计数问题可以在端点标记1和-1 3. 离散化+线段树 终于会了:) ()
代码1:离散化+线段树
/************************************************* Author :Running_Time* Created Time :2015-8-25 8:55:54* File Name :F.cpp ************************************************/#include #include #include #include #include #include #include #include #include #include #include #include #include
代码2:二分查找
/************************************************* Author :Running_Time* Created Time :2015-8-25 8:55:54* File Name :F.cpp ************************************************/#include #include #include #include #include #include #include #include #include #include #include #include #include
代码3:尺取法
#include #include #include using namespace std;typedef long long ll;typedef pair P;const int N = 1e5 + 10;const int INF = 0x3f3f3f3f;P p[N], q[N];int ans[N];int n, m;int main(void) { int T, cas = 0; scanf ("%d", &T); while (T--) { scanf ("%d%d", &n, &m); int tot = 0; for (int a, b, i=1; i<=n; ++i) { scanf ("%d%d", &a, &b); p[++tot] = P (a, 1); p[++tot] = P (b + 1, -1); } sort (p+1, p+1+tot); for (int i=1; i<=m; ++i) { int x; scanf ("%d", &x); q[i] = P (x, i); } sort (q+1, q+1+m); printf ("Case #%d:\n", ++cas); for (int j=1, cnt=0, i=1; i<=m; ++i) { while (j <= tot && p[j].first <= q[i].first) { cnt += p[j].second; ++j; } ans[q[i].second] = cnt; } for (int i=1; i<=m; ++i) printf ("%d\n", ans[i]); } return 0;}