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

思路:将蔬菜的价值看做高度的话,题目就转化成求体积并,这样就容易了。
   与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. IIS 配置错误解决方法集合

    问题:405 - 不允许用于访问此页的 HTTP 谓词 解决:IIS处理程序映射中添加模块映射,模块选择:ServerSideIncludeModule,名称:SSINC-HTML

  2. Maven系列--pom.xml 配置详解

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  3. SQLite数据库与Contentprovider(1)

    SQlite:类似mysql的数据库.把数据保存到.db文件夹中. Contentprovider:一般用于不同进程之间的数据共享(两个APP). 手动建库:http://www.runoob.com ...

  4. Android:简单实现ViewPager+TabHost+TabWidget实现导航栏导航和滑动切换

    viewPager是v4包里的一个组件,可以实现滑动显示多个界面. android也为viewPager提供了一个adapter,此adapter最少要重写4个方法: public int getCo ...

  5. JavaScript高级程序设计之EventUtil

    简单的通用事件方法 var EventUtil = { getEvent: function (e) { return e || window.event; }, getTarget: functio ...

  6. CoreLocation简单应用

    1.获取locationManager let locationManager: CLLocationManager = CLLocationManager() 2.设置locationManager ...

  7. (转)前端构建工具gulp入门教程

    前端构建工具gulp入门教程 老婆婆 1.8k 2013年12月30日 发布 推荐 10 推荐 收藏 83 收藏,20k 浏览 本文假设你之前没有用过任何任务脚本(task runner)和命令行工具 ...

  8. 解决sharepoint 2010 用户配置文件同步服务 正在启动

    用户配置文件同步服务一直显示“正在启动”,而且无法停止,如下办法可以停止这个服务: 在sharepoint power shell 中执行下面的命令: Get-spserviceinstance 获取 ...

  9. Nginx + django windows下配置

    1.下载nginx, 去http://nginx.org/en/download.html 下载,我下载的是1.8 stable版本. 2.配置文件/conf/nginx.conf #user nob ...

  10. 65.OV7725图像倒置180度

    采集的图像倒置180度,这跟寄存器的设置有关.寄存器0X32的bit[7]可以变换倒置方向.