离散化+线段树/二分查找/尺取法 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 ...
随机推荐
- Javascript setTimeout(0),闭包
setTimeout常常被用于延迟运行某个函数,使用方法为 setTimeout(function(){ - }, timeout); 有时为了进行异步处理,而使用setTimeout(functio ...
- hdu1181 dfs搜索之变形课
原题地址 这道题数据据说比較水,除了第一组数据是Yes以外.其余都是No.非常多人抓住这点就水过了.当然了,我认为那样过了也没什么意思.刷oj刷的是质量不是数量. 这道题从题目上来看是个不错的 搜索题 ...
- java 实现打印当前月份的日历
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcTc0NTQwMTk5MA==/font/5a6L5L2T/fontsize/400/fill/I0JBQk ...
- 微信小程序实战之 pay(支付页面)
项目目录: 逻辑层: pay.js // pages/pay/pay.js Page({ /** * 页面的初始数据 */ data: { resultType: "", resu ...
- Linux下进程信息的深入分析
这里我们主要介绍进程的状态,进程的状态可以通过/proc/PID/status来查看,也可以通过/proc/PID/stat来查看. 如果说到工具大家用的最多的ps也可以看到进程的信息.这里我们通过/ ...
- linux之rsync远程数据同步备份
rsync服务是一种高效的远程数据备份的工具,该服务的port号为873, 是Liunx下的一种非独立服务.由xinetd超级服务管理,取代监听873port. 长处: 1.rsync能够利用ssh和 ...
- 【CODEFORCES】 C. Dreamoon and Strings
C. Dreamoon and Strings time limit per test 1 second memory limit per test 256 megabytes input stand ...
- 修正iOS从照相机和相册中获取的图片 方向
修正iOS从照相机和相册中获取的图片 方向 修正iOS从照相机和相册中获取的图片 方向 使用系统相机拍照得到的图片的默认方向有时不是ImageOrientationDown,而是ImageOrie ...
- FileWriter简单用法并记录日志
import java.io.*; import java.util.Date; /** * Created by Administrator on 2018/4/6. */ public class ...
- 【视频】零基础学Android开发:蓝牙聊天室APP(三)
零基础学Android开发:蓝牙聊天室APP第三讲 3.1 ImageView.ImageButton控件具体解释 3.2 GridView控件具体解释 3.3 SimpleAdapter适配器具体解 ...