poj 3277 City Horizon 线段树
2013-04-14 19:40
113 查看
这个题目要是做过矩形面积并的话其实可以直接上扫描线的做法,我第一感觉就是想这样做的,但是细想想的话,其实是不需要的,因为这些矩形的低都在同一水平线上,所以想到用线段树来维护水平线的高度的做法,这个思路因为不是严格的logn的,所以tle了。
后来想到另外一种做法,先把矩形按照高度排序,那么每次插入的矩形只要底是被用过的话,那么这个矩形肯定被完全覆盖了,那么就只需要依次线查询矩形底部没有用过的长度,乘以当前矩形的高度,累加就是答案了。这种方案的话因为修改和查询都是严格logn的,所以比上面的会快一些,最后1s过的。
这个题目还要离散化处理,我用的是set来做这个工作,然后数据范围会超ll,要想好怎么处理。
后来想到另外一种做法,先把矩形按照高度排序,那么每次插入的矩形只要底是被用过的话,那么这个矩形肯定被完全覆盖了,那么就只需要依次线查询矩形底部没有用过的长度,乘以当前矩形的高度,累加就是答案了。这种方案的话因为修改和查询都是严格logn的,所以比上面的会快一些,最后1s过的。
这个题目还要离散化处理,我用的是set来做这个工作,然后数据范围会超ll,要想好怎么处理。
#include <iostream> #include <stdio.h> #include <string.h> #include <set> #include <algorithm> #define ls t<<1 #define rs t<<1|1 #define midt(tr[t].l+tr[t].r)>>1 #define ll long long using namespace std; const int maxn=40000+10; int x[maxn<<1]; set<int> xx; struct data { int a,b,h; bool operator<(const data &xx) const { return(h<xx.h); } }d[maxn]; struct { int l,r; ll a,b,sum; int lazy; }tr[maxn<<3]; void maketree(int t,int l,int r) { tr[t].l=l; tr[t].r=r; tr[t].a=x[l]; tr[t].b=x[r]; tr[t].lazy=0; tr[t].sum=x[r]-x[l]; // printf("%lld\n",tr[t].sum); if(l+1==r) return; int mid=midt; maketree(ls,l,mid); maketree(rs,mid,r); } void pushdown(int t) { tr[ls].lazy=tr[t].lazy; tr[rs].lazy=tr[t].lazy; tr[ls].sum=0; tr[rs].sum=0; tr[t].lazy=0; } void modify(int t,int a,int b) { if(a<=tr[t].a&&b>=tr[t].b) { tr[t].sum=0; tr[t].lazy=1; return; } if(tr[t].lazy) pushdown(t); int mid=midt; if(a<x[mid]) modify(ls,a,b); if(x[mid]<b) modify(rs,a,b); tr[t].sum=tr[ls].sum+tr[rs].sum; } ll query(int t,int a,int b) { if(a<=tr[t].a&&b>=tr[t].b) return(tr[t].sum); int mid=midt; if(tr[t].lazy) pushdown(t); ll ret=0; if(a<x[mid]) ret+=query(ls,a,b); if(x[mid]<b) ret+=query(rs,a,b); return(ret); } int main() { int n; while(scanf("%d",&n)!=EOF) { xx.clear(); for(int i=1;i<=n;i++) { scanf("%d%d%d",&d[i].a,&d[i].b,&d[i].h); xx.insert(d[i].a); xx.insert(d[i].b); } int j=0; for(set<int>::iteratori=xx.begin();i!=xx.end();i++) x[++j]=*i; sort(d+1,d+1+n); maketree(1,1,j); ll ans=0; for(int i=n;i>=1;i--) { ans+=query(1,d[i].a,d[i].b)*d[i].h; modify(1,d[i].a,d[i].b); } printf("%lld\n",ans); } return 0; }
相关文章推荐
- 【线段树】 POJ 3277 City Horizon 裸扫描线
- 【线段树】 POJ 3277 City Horizon 裸扫描线
- POJ 3277 City Horizon(线段树+扫描线+离散化)
- poj-3277-City Horizon-离散化+线段树区域更新
- POJ 3277 City Horizon (离散化线段树)
- poj 3277 City Horizon(线段树#2----离散化)
- (离散化 + 线段树) poj 3277 City Horizon
- poj 3277 City Horizon (线段树 扫描线 矩形面积并)
- Poj 3277 City Horizon - 线段树
- poj 3277 City Horizon 线段树加上离散化
- POJ 3277 City Horizon(扫描线+线段树)
- 离散化+线段树 POJ 3277 City Horizon
- POJ 3277 City Horizon 扫描线+离散化+线段树
- poj 3277 city horizon 线段树
- poj 3277(线段树+离散化)
- POJ 3277 City Horizon【map模板】【stl练习】
- POJ 3277 线段树 + 延迟标记
- POJ 3277线段树 离线+离散
- poj 3277 City Horizon
- poj 3277 City Horizon