Flowers

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2616    Accepted Submission(s):
1287

Problem Description
As is known to all, the blooming time and duration
varies between different kinds of flowers. Now there is a garden planted full of
flowers. The gardener wants to know how many flowers will bloom in the garden in
a specific time. But there are too many flowers in the garden, so he wants you
to help him.
 
Input
The first line contains a single integer t (1 <= t
<= 10), the number of test cases.
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 Si and Ti (1 <= Si
<= Ti <= 10^9), means i-th flower will be blooming at time
[Si, Ti].
In the next M lines, each line contains an
integer Ti, means the time of i-th query.
 
Output
For each case, output the case number as shown and then
print M lines. Each line contains an integer, meaning the number of blooming
flowers.
Sample outputs are available for more details.
 
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
 
题意:给出花的种类n以及m个要查询的时间,接下来n行是每种花的开放区间(其中一些花的开放区间有重合的部分),接下来m个数非别表示要查询的点(查询在这个时间点,有多少种花开放)
 
题解:直接线段树建图的话由于数据达到了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的树,大大浪费了空间,
 
AC代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define LL long long
#define MAX 100100
using namespace std;
int s[MAX],e[MAX],q[MAX];
int rec[MAX];//记录所有值排序后的下标
int add[MAX<<2];
int sum[MAX<<2];
int le[MAX],ri[MAX];
void pushup(int o)
{
sum[o]=sum[o<<1]+sum[o<<1|1];
}
void pushdown(int o,int m)
{
if(add[o])
{
add[o<<1]+=add[o];
add[o<<1|1]+=add[o];
sum[o<<1]+=add[o]*(m-(m>>1));
sum[o<<1|1]+=add[o]*(m>>1);
add[o]=0;
}
}
void gettree(int o,int l,int r)
{
add[o]=0;
if(l==r)
{
sum[o]=0;
return ;
}
int mid=(l+r)>>1;
gettree(o<<1,l,mid);
gettree(o<<1|1,mid+1,r);
pushup(o);
}
void update(int o,int l,int r,int L,int R,int val)
{
if(L<=l&&R>=r)
{
add[o]+=val;
sum[o]+=val*(r-l+1);
return ;
}
pushdown(o,r-l+1);
int mid=(l+r)>>1;
if(L<=mid)
update(o<<1,l,mid,L,R,val);
if(R>mid)
update(o<<1|1,mid+1,r,L,R,val);
pushup(o);
}
int find(int o,int l,int r,int pos)
{
if(l==r)
{
return sum[o];
}
pushdown(o,r-l+1);
int ans=0;
int mid=(l+r)>>1;
if(pos<=mid)
ans=find(o<<1,l,mid,pos);
else
ans=find(o<<1|1,mid+1,r,pos);
return ans;
}
int query(int l,int r,int pos)//查找输入当前值,在树中对应的位置
{
while(r>=l)
{
int mid=(l+r)>>1;
if(rec[mid]==pos)
return mid;
else if(rec[mid]>pos)
r=mid-1;
else
l=mid+1;
}
return -1;
}
int main()
{
int t,n,m,k,i;
scanf("%d",&t);
k=1;
int maxx;
while(t--)
{
scanf("%d%d",&n,&m);
int p=1;
for(i=0;i<n;i++)
{
scanf("%d%d",&s[i],&e[i]);
rec[p++]=s[i];
rec[p++]=e[i];
}
for(i=0;i<m;i++)
{
scanf("%d",&q[i]);
rec[p++]=q[i];
}
sort(rec+1,rec+p);//
int R=2;
for(i=2;i<p;i++)//去除数组中重复的点
{
if(rec[i]!=rec[i-1])
rec[R++]=rec[i];
}
sort(rec+1,rec+R);
gettree(1,1,R-1);//对下标建树
for(int i=0;i<n;i++)
{
int x=query(1,R-1,s[i]);
int y=query(1,R-1,e[i]);
update(1,1,R-1,x,y,1);
}
printf("Case #%d:\n",k++);
for(i=0;i<m;i++)
{
int x=query(1,R-1,q[i]);
printf("%d\n",find(1,1,R-1,x));
}
}
}

  

hdoj 4325 Flowers【线段树+离散化】的更多相关文章

  1. hdoj 4325 Flowers 线段树+离散化

    hdoj 4325 Flowers 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4325 思路: 直接线段树,按照花的开放区间的大小建树,要注意虽然 ...

  2. POJ 2528 Mayor's posters(线段树+离散化)

    Mayor's posters 转载自:http://blog.csdn.net/winddreams/article/details/38443761 [题目链接]Mayor's posters [ ...

  3. poj 2528 Mayor's posters(线段树+离散化)

    /* poj 2528 Mayor's posters 线段树 + 离散化 离散化的理解: 给你一系列的正整数, 例如 1, 4 , 100, 1000000000, 如果利用线段树求解的话,很明显 ...

  4. [poj2528] Mayor's posters (线段树+离散化)

    线段树 + 离散化 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayor ...

  5. [UESTC1059]秋实大哥与小朋友(线段树, 离散化)

    题目链接:http://acm.uestc.edu.cn/#/problem/show/1059 普通线段树+离散化,关键是……离散化后建树和查询都要按照基本法!!!RE了不知道多少次………………我真 ...

  6. poj 2528 Mayor's posters 线段树+离散化技巧

    poj 2528 Mayor's posters 题目链接: http://poj.org/problem?id=2528 思路: 线段树+离散化技巧(这里的离散化需要注意一下啊,题目数据弱看不出来) ...

  7. BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针

    BZOJ_4653_[Noi2016]区间_线段树+离散化+双指针 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间, ...

  8. D - Mayor's posters(线段树+离散化)

    题目: The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campai ...

  9. 主席树||可持久化线段树+离散化 || 莫队+分块 ||BZOJ 3585: mex || Luogu P4137 Rmq Problem / mex

    题面:Rmq Problem / mex 题解: 先离散化,然后插一堆空白,大体就是如果(对于以a.data<b.data排序后的A)A[i-1].data+1!=A[i].data,则插一个空 ...

  10. HDU5124:lines(线段树+离散化)或(离散化思想)

    http://acm.hdu.edu.cn/showproblem.php?pid=5124 Problem Description John has several lines. The lines ...

随机推荐

  1. Tomcat Java内存溢出 PermGen space 解决方案

    -Xms300m -Xmx400m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256M

  2. Git教程之使用GitHub

    我们一直用GitHub作为免费的远程仓库,如果是个人的开源项目,放到GitHub上是完全没有问题的.其实GitHub还是一个开源协作社区,通过GitHub,既可以让别人参与你的开源项目,也可以参与别人 ...

  3. MyEclipse常用设置笔记

    1. Myeclipse下去掉SVN用户名和密码,就只能删除Subversion的auth目录 windows平台 Win7: 1.进入c:/Users/[你的用户名]/AppData/Roaming ...

  4. Android开发之实用小知识点汇总-2

    1.EditText 中将光标移到文字末尾: EditText mEdit = (EditText)this.findViewById(R.id.EditText01); mEdit .setText ...

  5. mac tree命令

    mac下默认是没有 tree命令的,不过我们可以使用find命令模拟出tree命令的效果,如显示当前目录的 tree 的命令: $ find . -print | sed -e 's;[^/]*/;| ...

  6. hdu4745Two Rabbits(dp)

    链接 哎..比赛中一下想到了公共子序 之后思维就被局限了 一直在这附近徘徊 想着怎么优化 怎么预处理.. 观看了众多神牛的代码 ..以前觉得自己能写出个记忆化的最长回文长度 还挺高兴的...现在觉得好 ...

  7. 三维软件转Unity的系统单位设置研究

    Unity的系统单位为米,其他3D软件的模型导入,而保持和Unity的比例一致是非常重要的,下面对各软件进行测试: ㈠. 3dsmax 转 Unity的比例为100:1:也就是说Unity单位是3ds ...

  8. 【Java基础之容器】Iterator

    Iterator: ->所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现了Iterator接口的对象 ->Iterator对象称作迭代器,用以方便的实 ...

  9. linux chmod 命令详解(转)

    Ubuntu下修改目录权限需要先用 sudo 来获得管理员权限,格式如下: sudo chmod 600 ××× (只有所有者有读和写的权限)sudo chmod 644 ××× (所有者有读和写的权 ...

  10. UVA 12436-Rip Van Winkle's Code(线段树的区间更新)

    题意: long long data[250001]; void A( int st, int nd ) { for( int i = st; i \le nd; i++ ) data[i] = da ...