题意:在一块地上种蔬菜,每种蔬菜有个价值。对于同一块地蔬菜价值高的一定是最后存活,求最后的蔬菜总值。

思路:将蔬菜的价值看做高度的话,题目就转化成求体积并,这样就容易了。
   与HDU 3642 Get The Treasury 同样求体积并,只不过HDU 3642 是要求覆盖大于等于3次的体积并,该题比那道题容易些。

   先将蔬菜价值(即高度)从小到大排序,然后一层一层地开始扫描,计算每层中的面积并,这个就同二维扫描一样。
     然后再用面积乘以这层的高度,即得到该层的体积并。然后所有层的体积加起来,即为所求。

一开始RE。。。
后来仔细看了代码,再看看题意,发现x,y的绝对值小于10^6,也就是有可能为负数,而原本建立了一个数组hashx,
建立x坐标到离散值的映射,之所以RE是因为x<0的话下标就越界了。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define lson rt<<1,L,mid
#define rson rt<<1|1,mid,R using namespace std;
const int maxn=;
int n,m;
int xval[maxn<<]; //存储x坐标
//int hashx[1000005]; //建立横坐标——离散值的映射,一开始没注意题目中说明:x,y的绝对值小于10^6,也就是有可能为负数,不能用hashx
int hashkey[maxn<<]; //建立离散值——坐标的映射,然后用二分搜索对应的离散值
int idx,hidx; //idx为xval数组的下标,hidx用于x坐标的离散化
int price[]; //蔬菜价格 struct Line{
int l,r,y;
int tp; //标记矩形的上边界(tp=-1)和下边界(tp=1)
int hight; //hight为该区域种的蔬菜价值,表示该线条所处的高度范围,0~hight
bool operator<(const Line tmp)const{
return y<tmp.y;
}
}line[maxn<<]; struct Node{
int cnt;
long long sum;
long long len;
}tree[maxn<<]; void build(int rt,int L,int R){
tree[rt].cnt=;
tree[rt].len=hashkey[R]-hashkey[L];
tree[rt].sum=;
if(L+==R)
return;
int mid=(L+R)>>;
build(lson);
build(rson);
}
void pushUp(int rt,int L,int R){
if(tree[rt].cnt){
tree[rt].sum=tree[rt].len;
}
else{
if(L+==R){
tree[rt].sum=;
}
else{
tree[rt].sum=tree[rt<<].sum+tree[rt<<|].sum;
}
}
}
void update(int rt,int L,int R,int l,int r,int c){
if(l<=L&&R<=r){
tree[rt].cnt+=c;
pushUp(rt,L,R);
return;
}
int mid=(L+R)>>;
if(l<mid)
update(lson,l,r,c);
if(r>mid)
update(rson,l,r,c); /*
if(r<=mid)
update(lson,l,r,c);
else if(l>=mid)
update(rson,l,r,c);
else{
update(lson,l,mid,c);
update(rson,mid,r,c);
}
*/
pushUp(rt,L,R);
}
int binarySearch(int m){
int l=,r=hidx+,mid;
while(r-l>){
mid=(l+r)>>;
if(hashkey[mid]<=m)
l=mid;
else
r=mid;
}
return l;
}
int main()
{
int t;
int x1,y1,x2,y2,s;
scanf("%d",&t);
for(int q=;q<=t;q++){
scanf("%d%d",&n,&m);
memset(price,,sizeof(price));
for(int i=;i<=m;i++){
scanf("%d",&price[i]);
}
idx=-;
for(int i=;i<=n;i++){
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&s);
line[*i-].l=x1;line[*i-].r=x2;line[*i-].y=y1;line[*i-].hight=price[s];line[*i-].tp=;
line[*i].l=x1;line[*i].r=x2;line[*i].y=y2;line[*i].hight=price[s];line[*i].tp=-;
xval[++idx]=x1;
xval[++idx]=x2;
}
n*=;
sort(line+,line+n+);
sort(xval,xval+idx+);
hidx=;
//hashx[xval[0]]=hidx;
hashkey[hidx]=xval[];
for(int i=;i<=idx;i++){
if(xval[i]!=xval[i-]){
//hashx[xval[i]]=++hidx; xval[i]有可能为负数啊!!!所以才导致RE。。。
hashkey[++hidx]=xval[i];
}
} long long ans=;
int a,b;
sort(price+,price+m+);
long long sum=;
//枚举每一层
for(int w=;w<=m;w++){
int last=;
long long s=; //该层的面积
build(,,hidx); //是在这里build,一开始写在外层循环外面了。。。
for(int i=;i<=n;i++){
if(line[i].hight>=price[w]){
s+=tree[].sum*(line[i].y-line[last].y);
a=binarySearch(line[i].l);
b=binarySearch(line[i].r);
update(,,hidx,a,b,line[i].tp);
last=i;
}
}
sum+=s*(price[w]-price[w-]); //该层的体积
} printf("Case %d: %I64d\n",q,sum);
}
return ;
}

HDU 3255 Farming (线段树+扫面线,求体积并)的更多相关文章

  1. hdu 3255 Farming(扫描线)

    题目链接:hdu 3255 Farming 题目大意:给定N个矩形,M个植物,然后给定每一个植物的权值pi,pi表示种植物i的土地,单位面积能够收获pi,每一个矩形给定左下角和右上角点的坐标,以及s, ...

  2. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  3. hdu 4288 离线线段树+间隔求和

    Coder Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  4. hdu 3016 dp+线段树

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  5. HDU 5877 dfs+ 线段树(或+树状树组)

    1.HDU 5877  Weak Pair 2.总结:有多种做法,这里写了dfs+线段树(或+树状树组),还可用主席树或平衡树,但还不会这两个 3.思路:利用dfs遍历子节点,同时对于每个子节点au, ...

  6. HDU 4638-Group(线段树+离线处理)

    题意: 给n个编号,m个查询每个查询l,r,求下标区间[l,r]中能分成标号连续的组数(一组内的标号是连续的) 分析: 我们认为初始,每个标号为一个组(线段树维护区间组数),从左向右扫序列,当前标号, ...

  7. HDU 3308 LCIS (线段树区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...

  8. HDU 2795 Billboard (线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795 题目大意:有一块h*w的矩形广告板,要往上面贴广告;   然后给n个1*wi的广告,要求把广告贴 ...

  9. hdu 5480 Conturbatio 线段树 单点更新,区间查询最小值

    Conturbatio Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=54 ...

随机推荐

  1. JavaWeb之 JSP:自定义标签

    当jsp的内置标签和jstl标签库内的标签都满足不了需求,这时候就需要开发者自定义标签. 自定义标签 下面我们先来开发一个自定义标签,然后再说它的原理吧! 自定义标签的开发步骤 步骤一 编写一个普通的 ...

  2. 迭代器、泛型和增强For

    Iterator hasNext  next Iterator 迭代器 Collection提供了一个遍历集合的通用方式,迭代器(Iterator). 获取迭代器的方式是使用Collection定义的 ...

  3. DOS通讯录

    #include"stdio.h" #include"string.h" #include"stdlib.h" FILE *fp; #def ...

  4. poj 3625 Building Roads

    题目连接 http://poj.org/problem?id=3625 Building Roads Description Farmer John had just acquired several ...

  5. umask设置导致的weblogic中的应用上传的文件没有权限打开

    去年,在公司的某一weblogic上部署的web应用上传文件后却没有读的权限.因为weblogic在Linux上部署,上传文件是mount到了一台安装了NFS的Windows Server上. 当时本 ...

  6. 基于Elasticsearch的自定义评分算法扩展

    实现思路: 重写评分方法,调整计算文档得分的过程,然后根据function_score或script_sort进行排序检索.   实现步骤: 1.新建java项目TestProject,引入Elast ...

  7. Objective-C-实例变量与属性的关系

    当在一个类创建一个属性,Xcode编译器就会自动产生一个带下划线的同名实例变量: 一般来说,如果getter这个属性采用下划线的方式获取效率更高,而setter采用self.属性名更加合理. 读取实例 ...

  8. Python - DICT 字典排序 - OrderedDict

    官方地址: https://docs.python.org/2/library/collections.html#collections.OrderedDict >>> # regu ...

  9. 【学习总结】iOS中NSNotification、delegate、KVO三者之间的区别与联系?

    在开发ios应用的时候,我们会经常遇到一个常见的问题:在不过分耦合的前提下,controllers间怎么进行通信.在IOS应用不断的出现三种模式来实现这种通信: 1.委托delegation: 2.通 ...

  10. Graceful degradation versus progressive enhancement

    http://ued.taobao.org/blog/2008/10/understanding-progressiveen-hancement-chs-translation/ http://www ...