题目大意:在一个二维平面上有好多点,给点加权,给定矩形长宽,放置该矩形使得矩形内(不含边框)中点的权值和最大。
题目没什么特别的,大概就是把每个点都变成矩形(和给定矩形等大),然后求一个点使得覆盖它的矩形的权值和最大,线段树+离散化+扫描线就可以解决了。
但是
但是
但是
大家看下题目……
卧槽简直是英文表白范文啊,我已经醉的嫑嫑的了。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define lc o<<1 #define rc o<<1|1 using namespace std; const int N=10000+5; typedef long long ll; struct Node{ int l,r,mx,add; }tr[N<<3]; void pushup(int o){ tr[o].mx=max(tr[lc].mx,tr[rc].mx); } void pushdown(int o){ if(tr[o].add){ tr[lc].add+=tr[o].add;tr[rc].add+=tr[o].add; tr[lc].mx+=tr[o].add;tr[rc].mx+=tr[o].add; tr[o].add=0; } } void build(int o,int l,int r){ tr[o].l=l;tr[o].r=r;tr[o].mx=tr[o].add=0; if(l==r)return; int mid=l+r>>1; build(lc,l,mid);build(rc,mid+1,r); } void update(int o,int a,int b,int v){ int l=tr[o].l,r=tr[o].r; if(l==a&&b==r)tr[o].add+=v,tr[o].mx+=v; else{ int mid=l+r>>1; pushdown(o); if(b<=mid)update(lc,a,b,v); else if(mid<a)update(rc,a,b,v); else update(lc,a,mid,v),update(rc,mid+1,b,v); pushup(o); } } struct Segment{ double l,r,x; int v; bool operator <(const Segment &rhs)const{ return x<rhs.x; } }s[N<<1]; double hash[N<<1]; int main(){ //freopen("a.in","r",stdin); int n;double h,w; while(scanf("%d%lf%lf",&n,&h,&w)==3){ double x,y,xx=h/2.0-0.1,yy=w/2.0-0.1;int c; for(int i=1;i<=n;i++){ scanf("%lf%lf%d",&x,&y,&c); s[2*i-1]=(Segment){y-yy,y+yy,x-xx,c}; s[2*i]=(Segment){y-yy,y+yy,x+xx,-c}; hash[2*i-1]=y-yy; hash[2*i]=y+yy; } sort(hash+1,hash+1+2*n);sort(s+1,s+1+2*n); build(1,1,2*n); int ans=0; for(int i=1;i<=2*n;i++){ int l=lower_bound(hash+1,hash+1+2*n,s[i].l)-hash, r=lower_bound(hash+1,hash+1+2*n,s[i].r)-hash; update(1,l,r,s[i].v); ans=max(ans,tr[1].mx); } printf("%d\n",ans); } return 0; }