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

思路:将蔬菜的价值看做高度的话,题目就转化成求体积并,这样就容易了。
   与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. 刀哥多线程之调度组gcd-12-group

    调度组 常规用法 - (void)group1 { // 1. 调度组 dispatch_group_t group = dispatch_group_create(); // 2. 队列 dispa ...

  2. C 基于UDP实现一个简易的聊天室

    引言 本文是围绕Linux udp api 构建一个简易的多人聊天室.重点看思路,帮助我们加深 对udp开发中一些api了解.相对而言udp socket开发相比tcp socket开发注意的细节要少 ...

  3. 菜鸟学习Spring——初识Spring

    一.概念. Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Develop ...

  4. 函数调用和inline作用

    函数调用的开销: 函数被调用时,要有函数调用和返回.要保存当前程序上下文信息,以便函数调用完毕后返回原来的地方,继续执行程序.将函数的参数进行压栈.出栈,执行函数,函数调用完毕后释放内部变量占用的内存 ...

  5. Unity3d Shortcuts

    参考:http://www.ceeger.com/Manual/ 场景视图导航  Click-drag to drag the camera around. 点击拖拽平移场景视图 Hold Alt a ...

  6. Android之使用HTTP协议的Get/Post方式向服务器提交数据

    1.Get方式 方法:通过拼接url在url后添加相应的数据,如:http://172.22.35.112:8080/videonews/GetInfoServlet?title=霍比特人&t ...

  7. ssh公钥免密码登录

    1,生成公钥 ssh-keygen -t rsa 2,上传至服务器 将个人电脑的公钥添加到服务器 cat id_rsa.pub >> ~/.ssh/authorized_keys 3,本地 ...

  8. wordpress 为文章内容添加自动过滤,例如为出站链接添加nofollow,也可以将淘宝客链接转换。。

    做seo的都明白,反向链接对与网站的优化有着很重要的作用,是搜索引擎给网站排名的一个重要因素.为了添加反向链接,SEO作弊者会在论坛和博客等大量发布带无关链接的 内容.这些垃圾链接的存在给搜索引擎对网 ...

  9. 失败的数据库迁移UDB

    公司采用的是ucloud的云主机,数据库也是架设在云主机上.由于数据越来越多数据查询数据越来越慢,所以我决定往 UDB上迁移.当时考虑的理由如下: (1)云主机底层架设在虚拟机上IO性能有折损,而UD ...

  10. 技术揭秘12306改造(一):尖峰日PV值297亿下可每秒出票1032张

    [编者按]12306网站曾被认为是"全球最忙碌的网站",在应对高并发访问处理方面,曾备受网民诟病. 2015年铁路客票春运购票高峰期已过,并且12306网站今年没"瘫痪& ...