HDU 4325 Flowers(线段树+离散化)
2015-12-06 17:45
309 查看
Description
给出n朵花的绽放时刻与凋谢时刻,并给出m次查询,每次查询一个时刻有多少朵花同时开放
Input
第一行为一整数t表示用例组数,每组用例第一行为两个整数n和m分别表示花的数量和查询的次数,之后n行每行两个整数s和e分别表示该朵花的绽放时刻和凋谢时刻,最后m行每行一个整数x表示查询在x时刻有多少朵花同时开放(1<=t<=10,1<=n,m<=10^5,1<=s<=e<=10^9)
Output
对于每次查询,输出查询结果
Sample Input
2
1 1
5 10
4
2 3
1 4
4 8
1
4
6
Sample Output
Case #1:
0
Case #2:
1
2
1
Solution
将所有花的绽放时刻,凋谢时刻以及查询的时刻放在一起排序后离散化建线段树,那么每朵花的开放就是对线段树的区间覆盖,查询就是对线段树的单点更新,注意离散化的时候要通过增点来去重
Code
给出n朵花的绽放时刻与凋谢时刻,并给出m次查询,每次查询一个时刻有多少朵花同时开放
Input
第一行为一整数t表示用例组数,每组用例第一行为两个整数n和m分别表示花的数量和查询的次数,之后n行每行两个整数s和e分别表示该朵花的绽放时刻和凋谢时刻,最后m行每行一个整数x表示查询在x时刻有多少朵花同时开放(1<=t<=10,1<=n,m<=10^5,1<=s<=e<=10^9)
Output
对于每次查询,输出查询结果
Sample Input
2
1 1
5 10
4
2 3
1 4
4 8
1
4
6
Sample Output
Case #1:
0
Case #2:
1
2
1
Solution
将所有花的绽放时刻,凋谢时刻以及查询的时刻放在一起排序后离散化建线段树,那么每朵花的开放就是对线段树的区间覆盖,查询就是对线段树的单点更新,注意离散化的时候要通过增点来去重
Code
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> using namespace std; #define maxn 111111 struct Tree { int left,right,sum,flag; }T[4*maxn]; int t,n,m,s[maxn],e[maxn],cnt,x[4*maxn],q[maxn]; void build(int l,int r,int t) { T[t].left=l; T[t].right=r; T[t].sum=T[t].flag=0; if(l==r) return ; int mid=(l+r)>>1; build(l,mid,2*t); build(mid+1,r,2*t+1); } void push_up(int t) { T[t].sum=T[2*t].sum+T[2*t+1].sum; } void push_down(int t) { if(T[t].flag) { T[2*t].flag+=T[t].flag; T[2*t+1].flag+=T[t].flag; T[2*t].sum+=(T[2*t].right-T[2*t].left+1)*T[t].flag; T[2*t+1].sum+=(T[2*t+1].right-T[2*t+1].left+1)*T[t].flag; T[t].flag=0; } } void update(int l,int r,int z,int t) { if(T[t].left==l&&T[t].right==r) { T[t].flag+=z; T[t].sum+=(r-l+1)*z; return ; } push_down(t); if(r<=T[2*t].right) update(l,r,z,2*t); else if(l>=T[2*t+1].left) update(l,r,z,2*t+1); else { update(l,T[2*t].right,z,2*t); update(T[2*t+1].left,r,z,2*t+1); } push_up(t); } int query(int tar,int t) { if(T[t].left==tar&&T[t].right==tar) return T[t].sum; push_down(t); if(tar<=T[2*t].right) return query(tar,2*t); return query(tar,2*t+1); } int get(int tar) { return lower_bound(x,x+cnt,tar)-x+1; } int main() { int res=1; scanf("%d",&t); while(t--) { cnt=0; printf("Case #%d:\n",res++); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d%d",&s[i],&e[i]); x[cnt++]=s[i],x[cnt++]=e[i]; } for(int i=1;i<=m;i++) { scanf("%d",&q[i]); x[cnt++]=q[i]; } //离散化 sort(x,x+cnt); cnt=unique(x,x+cnt)-x; for(int i=cnt-1;i>0;i--) if(x[i]-x[i-1]>1) x[cnt++]=x[i-1]+1; sort(x,x+cnt); build(1,cnt,1); for(int i=1;i<=n;i++) { int l=get(s[i]),r=get(e[i]);//二分搜索到这朵花的绽放与凋谢时间 update(l,r,1,1);//覆盖这朵花的开放区间 } for(int i=1;i<=m;i++) { int tar=get(q[i]);//二分搜索到这个查询时刻是树中哪个节点 printf("%d\n",query(tar,1)); } } return 0; }
相关文章推荐
- I/O流性能比拼
- POJ3295——Tautology
- Idea 15 64位安装
- 用Qemu模拟vexpress-a9 (五) --- u-boot引导kernel,device tree的使用
- mysql基础知识
- 《尘曲》
- OAF学习笔记-不基于EO的数据处理
- C 标准库 strstr 函数的实现
- nyoj99(欧拉路)
- TCMalloc小记
- 项目开发步骤
- hdu 1034 Candy Sharing Game
- c++ 虚表
- Hadoop 文件的数量怎么比block的数量多?
- Scala 点滴:"_" 方法 -> 函数
- ContentProvider 详解
- 20135337——信息安全设计基础第十二周学习笔记
- struts2国际化
- java1.7集合源码阅读:ArrayList
- 有理数类 Java BigInteger实现