离散化+线段树/二分查找/尺取法 HDOJ 4325 Flowers
题意:给出一些花开花落的时间,问某个时间花开的有几朵
分析:这题有好几种做法,正解应该是离散化坐标后用线段树成端更新和单点询问。还有排序后二分查找询问点之前总花开数和总花凋谢数,作差是当前花开的数量,放张图易理解:
还有一种做法用尺取法的思想,对暴力方法优化,对询问点排序后再扫描一遍,花开+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的更多相关文章
- BZOJ4653(区间离散化+线段树+决策单调尺取)
写得很好的题解 一眼过去很像是:排序,然后从前向后扫,有这个区间时插到树里,过去以后再删除.然后事实也是这样做的…… 具体起来: 1.如果考虑暴力的话,一种想法是枚举左端和右端要选取的区间(如果我们按 ...
- hdoj 4325 Flowers 线段树+离散化
hdoj 4325 Flowers 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4325 思路: 直接线段树,按照花的开放区间的大小建树,要注意虽然 ...
- hdu4614 线段树+二分 插花
Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N ...
- 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块
!!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...
- 南阳理工 题目9:posters(离散化+线段树)
posters 时间限制:1000 ms | 内存限制:65535 KB 难度:6 描述 The citizens of Bytetown, AB, could not stand that ...
- SGU 180 Inversions(离散化 + 线段树求逆序对)
题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=180 解题报告:一个裸的求逆序对的题,离散化+线段树,也可以用离散化+树状数组.因为 ...
- Codeforces Gym 100803G Flipping Parentheses 线段树+二分
Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...
- Codeforces Gym 100231B Intervals 线段树+二分+贪心
Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...
- 【POJ】2528 Mayor's posters ——离散化+线段树
Mayor's posters Time Limit: 1000MS Memory Limit: 65536K Description The citizens of Bytetown, A ...
随机推荐
- .NET 之 ORM 性能评测
.NET 之 ORM 性能评测 Why 你应该总能听到某ORM性能比Dapper高 你应该有如下疑问: 基准测试是否权威 基准测试的方式是否合理 基准测试的标准是否能够统一 统一基准测试标准/规范 如 ...
- kvm虚拟化学习笔记(一)之kvm虚拟化环境安装
平时一直玩RHEL/CentOS/OEL系列的操作,玩虚拟化也是采这一类系统,kvm在RHEL6系列操作系统支持比较好,本文采用采用OEL6.3操作系统,网上所有文章都说KVM比xen简单,我怎么感觉 ...
- Hibernate复习之Hibernate基本介绍
众所周知.眼下流行的面向对象的对象关系映射的Java持久层框架有MyBatis和Hibernate.他们都是对象关系映射ORM. 解决的主要问题就是对象-关系的映射.域模型和关系模型都分别建立在概念模 ...
- Lync 2013 与Exchange 2013 UM&UC 集成!
设置好对应的拨号计划.我们设置分机号码为4位: 配置好接入号码为5000: 配置自己主动助理号码为6000: 改动UM拨号模式为双模式: Set-UMService -identity Exch ...
- 无限级分类Asp.net Mvc实现
无限级分类Asp.net Mvc实现 无限级分类涉及到异步加载子类.加载当前类和匹配问题,现在做一个通用的实现. (一) 效果如下: (二)设计.实现及使用 (1)数据库 (a)表设计db ...
- webstorm 6.0 注册码
User Name: EMBRACE License Key: ===== LICENSE BEGIN ===== 24718-12042010 00001h6wzKLpfo3gmjJ8xoTPw ...
- 【Mongodb教程 第一课 】 MongoDB下载安装
MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种.它在许多场景下可用于替代传统的关系型数据库或键/值存储方式.Mongo使用C++开发.以window平台 ...
- Jenkins系列之-—04 配置用户和权限控制
一.安装插件 插件名称:Role-based Authorization Strategy Role Strategy Plugin插件可以对构建的项目进行授权管理,让不同的用户管理不同的项目. 二. ...
- 堆排序C++实现
//heap sort //堆排序能够分为两个过程.其一是建堆.其二是出堆 //堆是一种全然二叉树,所以它能够用数组进行存储. //堆可分为最大堆和最小堆.最大堆指任一节点的值都大于其左右孩子节点的值 ...
- Eclipse添加Qt插件
此文件仅为步骤操作作一个记录,以便以后方便查阅. 1.操作大体参考这个网站:http://blog.csdn.net/defonds/article/details/5013412 2.我的运行环境: ...