这道题用线段树做更方便更新和查询,但是其数据范围很大,因此要将离散化和线段树结合起来,算是一道比较经典的线段树+离散化的例题。

线段树的离散化有很多方法,在这里,我先用一次结点离散化,间接将源左右端点离散化的想法实现。(受到一个博客的启发)


  题意:贴海报-给出海报左右端点,然后顺序贴上,问最后有多少海报可见。

  直接贴上Code,具体解释在注释中有提及(有不懂的地方可以在纸上打个线段树草稿试试):

//贴海报-给出海报左右端点,顺序贴上,问最后有多少海报可见。
//Time:79Ms Memory:2712K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std; #define MAX 10005 struct Node {
int l, r, kind;
}tr[16*MAX]; //两端点加空点需要8-16*MAX数据量 struct Pos {
int num, id;
friend bool operator < (Pos p1, Pos p2) { return p1.num < p2.num; }
}pos[2*MAX]; int n, cnt;
int l[MAX], r[MAX];
bool v[MAX]; void build(int x,int l,int r)
{
tr[x].l = l; tr[x].r = r;
if (l == r) return;
int mid = (l + r) / 2;
build(2 * x, l, mid);
build(2 * x + 1, mid + 1, r);
} void update(int x,int l,int r,int k)
{
if (tr[x].l == l && tr[x].r == r) {
tr[x].kind = k;
return;
}
if (tr[x].kind) {
tr[2 * x].kind = tr[x].kind;
tr[2 * x + 1].kind = tr[x].kind;
tr[x].kind = 0;
}
int mid = (tr[x].l + tr[x].r) / 2;
if (r <= mid) update(2 * x, l, r, k);
else if (l > mid) update(2 * x + 1, l, r, k);
else {
update(2 * x, l, mid, k);
update(2 * x + 1, mid + 1, r, k);
}
} int query(int x,int l,int r)
{
if (tr[x].kind) {
if (v[tr[x].kind]) return 0;
else { v[tr[x].kind] = true; return 1;}
}
if (tr[x].l == tr[x].r) return 0; //由于有空点,可能会有tr[x].kind = 0
int mid = (tr[x].l + tr[x].r) / 2;
return query(2 * x, l, mid) + query(2 * x + 1, mid + 1, r);
} int main()
{
int T;
scanf("%d", &T);
while (T--) {
memset(tr, 0, sizeof(tr));
memset(v, 0, sizeof(v));
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d%d", &l[i], &r[i]);
pos[2 * i].num = l[i];
pos[2 * i + 1].num = r[i];
pos[2 * i].id = 2 * i; //偶数-左端点
pos[2 * i + 1].id = 2 * i + 1; //奇数-右端点
}
int last = pos[0].num;
cnt = 1;
sort(pos, pos + 2 * n);
for (int i = 0; i < 2 * n; i++)
{
if (last != pos[i].num) {
if (pos[i].num - last > 1)
cnt++; //不相邻时,中间空一点
cnt++;
last = pos[i].num;
}
int id = pos[i].id; //分别对左右端点离散化
id % 2 ? r[id/2] = cnt : l[id/2] = cnt;
}
build(1, 1, cnt);
for (int i = 0; i < n; i++)
update(1, l[i], r[i], i + 1);
printf("%d\n", query(1, 1, cnt));
} return 0;
}

ACM/ICPC 之 数据结构-线段树+区间离散化(POJ2528)的更多相关文章

  1. ACM/ICPC 之 数据结构-线段树思想(POJ2182,含O(n^2)插入式解法)

    这道题在一定程度上体现了线段树的一种用法,解决的问题是:对于总计n个元素的第i个元素,已知其在[1,i]上部分序列的排名,求第i个元素在所有n个元素中的排名. 当然这道题数据比较水,所以用O(n^2) ...

  2. 线段树区间离散化维护按秩合并并查集(可撤销)——牛客多校第八场E

    模板题..去网上学了可撤销的并查集.. /* 给定一个无向图,边的属性为(u,v,l,r),表示<u,v>可以通过的size为[l,r] 求出有多少不同的size可以从1->n 把每 ...

  3. ACM: Hotel 解题报告 - 线段树-区间合并

    Hotel Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Description The ...

  4. 线段树区间离散化——牛客多校E

    这个区间离散化把我调死了.. 总之用vector来离散化,然后叶子节点维护的是一段区间,记录下每个叶子结点的起点+长度 千万要注意下标不能弄错! #include<bits/stdc++.h&g ...

  5. hiho1116 - 数据结构 线段树(区间合并)

    题目链接 现在有一个有n个元素的数组a1, a2, ..., an. 记f(i, j) = ai * ai+1 * ... * aj. 初始时,a1 = a2 = ... = an = 0,每次我会修 ...

  6. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

  7. POJ-2528 Mayor's posters (线段树区间更新+离散化)

    题目分析:线段树区间更新+离散化 代码如下: # include<iostream> # include<cstdio> # include<queue> # in ...

  8. POJ 2528 Mayor's posters (线段树区间更新+离散化)

    题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值 ...

  9. POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化)

    POJ.2528 Mayor's posters (线段树 区间更新 区间查询 离散化) 题意分析 贴海报,新的海报能覆盖在旧的海报上面,最后贴完了,求问能看见几张海报. 最多有10000张海报,海报 ...

随机推荐

  1. 用apache-cxf生成webservice客户端的时候报错Parameter: shead already exists for method

    版本apache-cxf-3.1.0 命令如下:wsdl2java -p com.wz.interfaces -d ./src -client ./ws/xxx.wsdl 报错如下: WSDLToJa ...

  2. 【11-23】window常用知识

    tips msconfig :管理应用程序加载启动项,也可以通过我的计算机查看 service.msc :管理windows本地服务 命令行:net start :显示所有启动的服务,不加分号 net ...

  3. hdu4951 Multiplication table (乘法表的奥秘)

    http://acm.hdu.edu.cn/showproblem.php?pid=4951 2014多校 第八题 1008 2014 Multi-University Training Contes ...

  4. KNN-实现文本分类

    现在大多程序.关于算法的都封装的差不多了... 所以很多程序猿很少来进行深入来研究了... 以前也想过自己好好学习下.但是理论确实难以下咽.怪我喽... 这次项目中需要用到了.要实现对文本进行分类的一 ...

  5. NFS服务器简介

    1.NFS为Network File System(网络文件系统):不同机器不同的操作系统可以彼此共享数据文件.      NFS的配置简单,启动remote procedure call(RPC, ...

  6. Js设置及获取Cookie的方法

    Login页面设置Cookie: <script type="text/javascript"> if(json.result=="true") { ...

  7. Go - 内置函数大全

    Package builtin import "builtin" Overview Index Overview ▾ Package builtin provides docume ...

  8. 软件测试-----Graph Coverage作业

    /******************************************************* * Finds and prints n prime integers * Jeff ...

  9. webApp前端开发技巧总结

    自Iphone和Android这两个牛逼的手机操作系统发布以来,在互联网界从此就多了一个新的名词-WebApp(意为基于WEB形式的应用程序,运行在高端的移动终端设备.我相信各位童鞋应该和我一个样子, ...

  10. 学C++50条建议

    1.把C++当成一门新的语言学习(和C没啥关系!真的.): 2.看<Thinking In C++>,不要看<C++变成死相>: 3.看<The C++ Programm ...