JZOJ 4898 人生的价值(线段树、扫描线)
2016-11-16 20:53
288 查看
题目大意
YYHS的校园可以抽象成一个无限二维平面,校园里分布着N个教室(编号为1..N),第i个教室的坐标为(x[i], y[i]),里面有w[i]个学生。新食堂的饭菜十分美味,然而同学们都比较懒。当且仅当新食堂的位置和第i个教室的位置的曼哈顿距离小于等于L,第i个教室里的学生会去新食堂吃饭。有博爱之心的NiroBC希望有尽量多的学生去新食堂吃饭,那么这个问题就交给你了!
n<=100,000,x,y,l<=100000
时间限制 1s
空间限制 256M
解题思路
经典扫描线。只不过要变换一下坐标,对于每一件教室,能让学生去新食堂的食堂位置的范围是一个以教室为中心的菱形,我们只需要这样:把教室坐标(x,y)变成(x-y,x+y),这样这个菱形就可以转化成正方形。
然后把这些正方形的左右对边分别取出来,混在一起排序。
之后从1~n+n扫描这些边,遇到正方形的左边就在线段树上纵坐标对应的区间上加上w,遇到右边就减去w。
#include<cstdio> #include<cstring> #include<algorithm> #define maxn 100006 #define fr(i,a,b) for(i=a;i<=b;i++) using namespace std; typedef long long ll; struct node { int x,y; } a[maxn]; struct nod { int x,z,st,en,w; } l[maxn+maxn]; bool cmp(nod a,nod b) { return a.x<b.x || a.x==b.x && a.z<b.z; } int i,n,lll,x,y,w,tot,s,ans,mx,tr[maxn*8],c[maxn*8]; void update(int v,int st,int en) { if (!c[v]) return; tr[v+v]+=c[v],tr[v+v+1]+=c[v]; c[v+v]+=c[v],c[v+v+1]+=c[v]; c[v]=0; return; } void modify(int v,int st,int en,int l,int r,int x) { if (st==l && en==r) { tr[v]+=x; c[v]+=x; return; } update(v,st,en); int m=(st+en) >> 1; if (r<=m) modify(v+v,st,m,l,r,x); else if (l>m) modify(v+v+1,m+1,en,l,r,x); else { modify(v+v,st,m,l,m,x); modify(v+v+1,m+1,en,m+1,r,x); } tr[v]=max(tr[v+v],tr[v+v+1]); return; } void findd(int v,int st,int en,int l,int r) { if (st==l && en==r) { s=max(s,tr[v]); return; } update(v,st,en); int m=(st+en) >> 1; if (r<=m) findd(v+v,st,m,l,r); else if (l>m) findd(v+v+1,m+1,en,l,r); else { findd(v+v,st,m,l,m); findd(v+v+1,m+1,en,m+1,r); } return; } int main() { freopen("value.in","r",stdin); freopen("value.out","w",stdout); scanf("%d%d",&n,&lll); fr(i,1,n) { scanf("%d%d%d",&x,&y,&w); a[i].x=x-y,a[i].y=x+y; l[i].x=a[i].x-lll,l[i].st=a[i].y-lll,l[i].en=a[i].y+lll,l[i].z=0,l[i].w=w; l[i+n].x=a[i].x+lll,l[i+n].st=a[i].y-lll,l[i+n].en=a[i].y+lll,l[i+n].z=1,l[i+n].w=w; l[i].st=max(l[i].st,1),l[i+n].st=max(l[i+n].st,1); l[i].en=max(l[i].en,1),l[i+n].en=max(l[i+n].en,1); mx=max(mx,a[i].y+lll); } tot=n+n; sort(l+1,l+tot+1,cmp); fr(i,1,tot) { if (l[i].z==0) modify(1,1,mx,l[i].st,l[i].en,l[i].w); s=0; findd(1,1,mx,l[i].st,l[i].en); ans=max(ans,s); if (l[i].z==1) modify(1,1,mx,l[i].st,l[i].en,-l[i].w); } printf("%d\n",ans); return 0; }
相关文章推荐
- 【jzoj4898】【人生的价值】【扫描线】【线段树】
- 【JZOJ4898】【NOIP2016提高A组集训第17场11.16】人生的价值
- 线段树(扫描线)求面积并, 交以及周长
- POJ1151(线段树+扫描线求矩形面积并)
- JZOJ 4895 三部曲(线段树)
- 人生的价值
- 扫描线 + 线段树 : 求矩形面积的并 ---- hnu : 12884 Area Coverage
- POJ 1177:线段树 离散化 扫描线
- 如何看待人生与技术的价值 推荐
- 线段树-扫描线
- HDU 1542 Atlantis 线段树 (扫描线 + 离散化)
- [JZOJ4610]线段树
- hdu 1542 Atlantis(线段树 线性扫描)
- HDU - 1255 覆盖的面积(线段树 + 扫描线)
- HDU - 1542 (扫描线+线段树优化)
- 【JZOJ3965】【Usaco2014 March Gold】The Lazy Cow(扫描线+线段树)
- [jzoj]4883. 【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰(线段树优化DP)
- 职业规划和人生价值的自我反思
- hdu 1255 覆盖的面积 (线段树 扫描线)
- hdu 3265 Posters(线段树,扫描线)