线段树或树状数组---Flowers
题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=4325
Description
Input
For each case, the first line contains two integer N and M, where N (1 <= N <= 10^5) is the number of flowers, and M (1 <= M <= 10^5) is the query times.
In the next N lines, each line contains two integer S i and T i (1 <= S i <= T i <= 10^9), means i-th flower will be blooming at time [S i, Ti].
In the next M lines, each line contains an integer T i, means the time of i-th query.
Output
Sample outputs are available for more details.
Sample Input
1 1
5 10
4
2 3
1 4
4 8
1
4
6
Sample Output
题意:有n种花,给了这n种花的花期时间,Si~Ti,求在某一时间t,有多少种花正在开放。
思路:这题给的花期时间数据为1~10^9,无法开辟这么大的数组,不能直接建树,必须先将数据进行离散化。离散化:在百科上看到一句很好的话:“离散化就是把连续的量,变成离散的量即变成一个一个的值”,例如区间(1,100)由于这是一个实数区间,其中间的值有无数个,如果我们能把它变为1到100内的整数,这样这些数就变成了有限个,即离散了; ,我们将每个区间的端点都存到一个数组中,然后将这些端点,按照从小到大排列(之后要去除这个数组中重复的点),并建立为与其下标的映射,然后用其下标建树,因为我们只是使用了需要的空间,并没有在整个空间上建树,这样就大大节省了空间和时间,如题中第二个例子,我们将所有数据按照从小到大排列后为1 2 3 4 6 8 分别对应下标1 2 3 4 5 6,此题数据小我们看不出明显的差别,但是如果数据中有区间(1000,10000),那差别马上就出来了,比如我们把题中的区间(4,8)换做(1000,10000)那么如果采用离散化思想,我们还是先排列大小 1 2 3 6 1000 10000对应下标1 2 3 4 5 6,我们只需建一棵根为6的树即可,如果不用离散化,我们就需要建造根为10000的树,大大浪费了空间。
然而!!!我发现同学他们的代码没有使用离散化,而是开辟了150000的空间就过了,很明显测试数据没有很大,都在150000以内,唉!所以可以不用离散化。
方法一:使用树状数组,若花期为t1~t2,更新t1-1及t1-1以下的子树根节点都减一,更新t2及t2以下的子树根节点加一,若求x时刻有多少种花正开着,将x及上方一路节点均相加,最后的和即是结果。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define N 152005
using namespace std;
int c[N]; int Lowbit(int t)
{ ///设k为t末尾0的个数,则求得为2^k=t&(t^(t-1));
return t&(t^(t-));
}
void update(int x,int t)
{
while(x > )
{
c[x]+=t;
x -= Lowbit(x);
}
}
int sum(int li)
{
int sum=;
while(li<=N)
{
sum+=c[li];
li=li+Lowbit(li);
}
return sum;
} int main()
{
int T;
int n,M,t1,t2,x,Case=;
scanf("%d",&T);
while(T--)
{
memset(c,,sizeof(c));
scanf("%d%d",&n,&M);
while(n--)
{
scanf("%d%d",&t1,&t2);
update(t1-,-);
update(t2,);
}
printf("Case #%d:\n",Case++);
while(M--)
{
scanf("%d",&x);
printf("%d\n",sum(x));
}
}
return ;
}
方法二:使用线段树进行区间更新。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int Max=;
int N,M;
int c[Max]; struct Node
{
int l,r;
int cnt;
}node[*Max]; void build(int L,int R,int i)
{
node[i].l=L;
node[i].r=R;
node[i].cnt=;
if(L==R) return;
int mid=(L+R)/;
build(L,mid,*i);
build(mid+,R,*i+);
} int update(int t1,int t2,int i)
{
if(node[i].l==t1&&node[i].r==t2)
{
node[i].cnt++;
return ;
}
int mid=(node[i].l+node[i].r)/;
if(t2<=mid) update(t1,t2,*i);
else if(t1>mid) update(t1,t2,*i+);
else
{
update(t1,mid,*i);
update(mid+,t2,*i+);
}
} int chazhao(int x,int i)
{
int sum=;
if(node[i].l<=x&&node[i].r>=x)
sum+=node[i].cnt;
if(node[i].l>x) return ;
if(node[i].r<x) return ;
sum+=chazhao(x,*i);
sum+=chazhao(x,*i+);
return sum;
} int main()
{
int T,t1,t2,Case=;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&N,&M);
build(,Max,);
for(int i=;i<=N;i++)
{
scanf("%d%d",&t1,&t2);
update(t1,t2,);
}
for(int i=;i<M;i++)
scanf("%d",&c[i]);
printf("Case #%d:\n",Case++);
for(int i=;i<M;i++)
{
printf("%d\n",chazhao(c[i],));
}
}
return ;
}
线段树或树状数组---Flowers的更多相关文章
- BZOJ2120:数颜色(数状数组套主席树)(带修改的莫对)
墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2. R P ...
- 5.15 牛客挑战赛40 E 小V和gcd树 树链剖分 主席树 树状数组 根号分治
LINK:小V和gcd树 时限是8s 所以当时好多nq的暴力都能跑过. 考虑每次询问暴力 跳父亲 这样是nq的 4e8左右 随便过. 不过每次跳到某个点的时候需要得到边权 如果直接暴力gcd的话 nq ...
- [bzoj1901][zoj2112][Dynamic Rankings] (整体二分+树状数组 or 动态开点线段树 or 主席树)
Dynamic Rankings Time Limit: 10 Seconds Memory Limit: 32768 KB The Company Dynamic Rankings has ...
- HDU 1556 线段树或树状数组,插段求点
1.HDU 1556 Color the ball 区间更新,单点查询 2.题意:n个气球,每次给(a,b)区间的气球涂一次色,问最后每个气球各涂了几次. (1)树状数组 总结:树状数组是一个查 ...
- HDU 3966 Aragorn's Story 树链剖分+树状数组 或 树链剖分+线段树
HDU 3966 Aragorn's Story 先把树剖成链,然后用树状数组维护: 讲真,研究了好久,还是没明白 树状数组这样实现"区间更新+单点查询"的原理... 神奇... ...
- 【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings
谁再管这玩意叫树状数组套主席树我跟谁急 明明就是树状数组的每个结点维护一棵动态开结点的权值线段树而已 好吧,其实只有一个指针,指向该结点的权值线段树的当前结点 每次查询之前,要让指针指向根结点 不同结 ...
- HDU 1394 Minimum Inversion Number(最小逆序数/暴力 线段树 树状数组 归并排序)
题目链接: 传送门 Minimum Inversion Number Time Limit: 1000MS Memory Limit: 32768 K Description The inve ...
- POJ 2299 Ultra-QuickSort 逆序数 树状数组 归并排序 线段树
题目链接:http://poj.org/problem?id=2299 求逆序数的经典题,求逆序数可用树状数组,归并排序,线段树求解,本文给出树状数组,归并排序,线段树的解法. 归并排序: #incl ...
- Turing Tree_线段树&树状数组
Problem Description After inventing Turing Tree, 3xian always felt boring when solving problems abou ...
随机推荐
- Swift 关键字汇总
常见的关键字有以下4种 与声明有关的关键字:class.deinit.enum.extension.func.import.init.let.protocol.static.struct.subscr ...
- JS - IE中没有console定义
由于IE中没有Console相关定义,所以不能使用它输出打印信息,且会出现脚本中断. 所以在IE中务必去掉(注释掉)console相关脚本代码.
- aspose.cell 设置excel里面的文字是超链接
目的: 1.通过方法designer.Workbook.Worksheets[0].Hyperlinks.Add("A1", 1, 1, url);给导出到excel里面的数据加上 ...
- tmux protocol version mismatch (client 7, server 6)
$ tmux attach protocol version mismatch (client 7, server 6) $ pgrep tmux 3429 $ /proc/3429/exe atta ...
- pdf嵌入字体
论文提交时,要求所有的字体都是嵌入的,为这个问题折腾了很久,发现了一个很好的答案,记一下: http://stackoverflow.com/questions/4231656/how-do-i-em ...
- 转载 jQuery的三种$()
$号是jQuery“类”的一个别称,$()构造了一个jQuery对象.所以,“$()”可以叫做jQuery的构造函数(个人观点,呵呵!). 1.$()可以是$(expresion),即css选择器 ...
- 理解js中的自由变量以及作用域的进阶
如果你不知道什么是作用域,建议你先看什么是作用域链,什么是原型链.这篇文章,因为这些内容都是有关联性的. 什么是自由变量? 如我在全局中定义了一个变量a,然后我在函数中使用了这个a,这个a就可以称之为 ...
- 【问题与思考】1+"1"=?
概述 在数学中1+1=2,在程序中1+1=2,而1+"1"=? 围绕着1+"1"的问题,我们来思考下这个问题. 目录: 一.在.Net代码中 二.在JavaSc ...
- AVL树(一)之 图文解析 和 C语言的实现
概要 本章介绍AVL树.和前面介绍"二叉查找树"的流程一样,本章先对AVL树的理论知识进行简单介绍,然后给出C语言的实现.本篇实现的二叉查找树是C语言版的,后面章节再分别给出C++ ...
- 使用 PSD Validator 在线校验 PSD 文件的质量
PSD Validator 可以帮助你在线校验 PSD 文件的质量,使用的规则来自 Photoshop Etiquette.Photoshop Etiquette 整理了 PSD 文件的规范,例如删 ...