题目传送门

题意:给出一些花开花落的时间,问某个时间花开的有几朵

分析:这题有好几种做法,正解应该是离散化坐标后用线段树成端更新和单点询问。还有排序后二分查找询问点之前总花开数和总花凋谢数,作差是当前花开的数量,放张图易理解:

还有一种做法用尺取法的思想,对暴力方法优化,对询问点排序后再扫描一遍,花开+1,花谢-1。详细看代码。

收获:一题收获很多:1. 降低复杂度可以用二分 2. 线段计数问题可以在端点标记1和-1 3. 离散化+线段树 终于会了:) (听说数据很水?)

代码1:离散化+线段树

/************************************************
* Author :Running_Time
* Created Time :2015-8-25 8:55:54
* File Name :F.cpp
************************************************/ #include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std; #define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
typedef pair<int, int> P;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
struct ST {
int sum[N<<2], col[N<<2]; void push_up(int rt) {
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void push_down(int rt, int len) {
if (col[rt]) {
col[rt<<1] += col[rt];
col[rt<<1|1] += col[rt];
sum[rt<<1] += col[rt] * (len - (len >> 1));
sum[rt<<1|1] += col[rt] * (len >> 1);
col[rt] = 0;
}
}
void build(int l, int r, int rt) {
col[rt] = 0; sum[rt] = 0;
if (l == r) return ;
int mid = (l + r) >> 1;
build (lson); build (rson);
// push_up (rt);
}
void updata(int ql, int qr, int l, int r, int rt) {
if (ql <= l && r <= qr) {
sum[rt] += (r - l + 1); col[rt] += 1; return ;
}
push_down (rt, r - l + 1);
int mid = (l + r) >> 1;
if (ql <= mid) updata (ql, qr, lson);
if (qr > mid) updata (ql, qr, rson);
// push_up (rt);
}
int query(int ql, int qr, int l, int r, int rt) {
if (ql <= l && r <= qr) return sum[rt];
push_down (rt, r - l + 1);
int mid = (l + r) >> 1;
if (ql <= mid) return query (ql, qr, lson);
if (qr > mid) return query (ql, qr, rson);
}
}st;
int x1[N], x2[N], q[N];
int X[N*3]; int my_binary_search(int l, int r, int key) {
while (l <= r) {
int mid = (l + r) >> 1;
if (X[mid] == key) return mid;
if (X[mid] < key) l = mid + 1;
else r = mid - 1;
}
return -1;
} int main(void) {
int T, cas = 0; scanf ("%d", &T);
while (T--) {
int n, m;
scanf ("%d%d", &n, &m);
int tot = 0;
for (int i=1; i<=n; ++i) {
scanf ("%d%d", &x1[i], &x2[i]);
X[tot++] = x1[i]; X[tot++] = x2[i];
}
for (int i=1; i<=m; ++i) {
scanf ("%d", &q[i]);
X[tot++] = q[i];
}
sort (X, X + tot);
int k = 1;
for (int i=1; i<tot; ++i) {
if (X[i] != X[i-1]) X[k++] = X[i];
} st.build (0, k, 1);
for (int ql, qr, i=1; i<=n; ++i) {
ql = lower_bound (X, X+k, x1[i]) - X;
qr = lower_bound (X, X+k, x2[i]) - X;
// ql = my_binary_search (0, k-1, x1[i]);
// qr = my_binary_search (0, k-1, x2[i]);
st.updata (ql, qr, 0, k, 1);
} printf ("Case #%d:\n", ++cas);
for (int p, i=1; i<=m; ++i) {
p = lower_bound (X, X+k, q[i]) - X;
// p = my_binary_search (0, k-1, q[i]);
printf ("%d\n", st.query (p, p, 0, k, 1));
}
} return 0;
}

代码2:二分查找

/************************************************
* Author :Running_Time
* Created Time :2015-8-25 8:55:54
* File Name :F.cpp
************************************************/ #include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std; #define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int x1[N], x2[N];
int n, m; int main(void) {
int T, cas = 0; scanf ("%d", &T);
while (T--) {
scanf ("%d%d", &n, &m);
for (int i=1; i<=n; ++i) {
scanf ("%d%d", &x1[i], &x2[i]);
}
sort (x1+1, x1+1+n); sort (x2+1, x2+1+n); printf ("Case #%d:\n", ++cas);
for (int i=1; i<=m; ++i) {
int p; scanf ("%d", &p);
printf ("%d\n", lower_bound (x1+1, x1+1+n, p) - (x1 + 1) - (lower_bound (x2+1, x2+1+n, p) - (x2 + 1)));
}
} return 0;
}

代码3:尺取法

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std; typedef long long ll;
typedef pair<int, int> 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;
}

离散化+线段树/二分查找/尺取法 HDOJ 4325 Flowers的更多相关文章

  1. BZOJ4653(区间离散化+线段树+决策单调尺取)

    写得很好的题解 一眼过去很像是:排序,然后从前向后扫,有这个区间时插到树里,过去以后再删除.然后事实也是这样做的…… 具体起来: 1.如果考虑暴力的话,一种想法是枚举左端和右端要选取的区间(如果我们按 ...

  2. hdoj 4325 Flowers 线段树+离散化

    hdoj 4325 Flowers 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4325 思路: 直接线段树,按照花的开放区间的大小建树,要注意虽然 ...

  3. hdu4614 线段树+二分 插花

    Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N ...

  4. 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块

    !!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...

  5. 南阳理工 题目9:posters(离散化+线段树)

    posters 时间限制:1000 ms  |  内存限制:65535 KB 难度:6   描述 The citizens of Bytetown, AB, could not stand that ...

  6. SGU 180 Inversions(离散化 + 线段树求逆序对)

    题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=180 解题报告:一个裸的求逆序对的题,离散化+线段树,也可以用离散化+树状数组.因为 ...

  7. Codeforces Gym 100803G Flipping Parentheses 线段树+二分

    Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...

  8. Codeforces Gym 100231B Intervals 线段树+二分+贪心

    Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...

  9. 【POJ】2528 Mayor's posters ——离散化+线段树

    Mayor's posters Time Limit: 1000MS    Memory Limit: 65536K   Description The citizens of Bytetown, A ...

随机推荐

  1. C# Queue与RabbitMQ的爱恨情仇(文末附源码):Q与MQ消息队列简单应用(二)

    上一章我们讲了队列( Queue),这一章我们讲Message Queue消息队列,简称MQ. 定义: MQ是MessageQueue,消息队列的简称(是流行的开源消息队列系统,利用erlang语言开 ...

  2. [转]Wireshark抓包工具--TCP数据包seq ack等解读

    原文: http://blog.csdn.net/wang7dao/article/details/16805337/ ---------------------------------------- ...

  3. 字符设备之poll机制

    poll机制作用:相当于一个定时器.时间到了还没有资源就唤醒进程. 主要用途就是:进程设置一段时间用来等待资源,假设时间到了资源还没有到来,进程就立马从睡眠状态唤醒不再等待.当然这仅仅是使用于这段时间 ...

  4. Hadoop架构设计、执行原理具体解释

    1.Map-Reduce的逻辑过程 如果我们须要处理一批有关天气的数据.其格式例如以下: 依照ASCII码存储.每行一条记录 每一行字符从0開始计数,第15个到第18个字符为年 第25个到第29个字符 ...

  5. CxImage的编译及简单使用举例

    1.  从http://sourceforge.net/projects/cximage/下载最新的CxImage 702源代码. 2.  解压缩后,以管理员身份打开CxImageFull_vc10. ...

  6. 使用python转换markdown to html

    起因 有很多编辑器可以直接将markdown转换成html,为什么还要自己写呢?因为我想写完markdown之后,即可以保存在笔记软件中(比如有道),又可以放到github进行版本管理,还可以发布到博 ...

  7. mt7620 uboot

    我本机装的是64位Ubuntu, SDK 里提供的 buildroot-gcc342 是32位的,无法直接运行,需要先安装 gcc-multilib. sudo apt-get install gcc ...

  8. Linux IO 多路复用是什么意思?

    写在前面:本文整理于知乎,原文链接为http://www.zhihu.com/question/32163005/answer/55772739,作者:罗志宇 再次向作者表示感谢~~ 假设你是一个机场 ...

  9. R.layout引用不了布局文件

    删除import android.R 引用包所在的R文件..

  10. Being a Hero (hdu 3251 最小割 好题)

    Being a Hero Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...