POJ 2482 Stars in Your Window

题目大意:在一个二维平面上有好多点,给点加权,给定矩形长宽,放置该矩形使得矩形内(不含边框)中点的权值和最大。

题目没什么特别的,大概就是把每个点都变成矩形(和给定矩形等大),然后求一个点使得覆盖它的矩形的权值和最大,线段树+离散化+扫描线就可以解决了。

但是

但是

但是

大家看下题目……

卧槽简直是英文表白范文啊,我已经醉的嫑嫑的了。

#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;
}


你可能感兴趣的:(POJ 2482 Stars in Your Window)