http://poj.org/problem?id=2482
题目
题目虐狗(T_T)
给一些星星,知道它们每个的亮度(1~100)和位置($0leqslant x,y<2^{31}$,坐标都是整数),也知道矩形的大小(长宽1000000以内),问把矩形放在哪里能得到的矩形内(不包括边框)星星亮度之和最大。

题解
考虑扫描线,考虑坐标为$(x,y)$的星星,一个矩形能包含星星可以等价于矩形的右上角在矩形$(x,y)sim(x+w,y+h)$以内,把这个矩形值设为v(不包括边框)
那么答案就是当前扫描线范围内值最大的矩形
因为不包括边框,所以我们可以把整个矩形长和宽朝矩形中心都减少$varepsilon$,然后把左下角平移到星星上
因为星星的坐标都是整数,因此$varepsilon<=1$,保证还能相交(重合也算),干脆直接取1
离散化x
为了保证重合也算,x相等的位置-v的事件应该在+v事件之后
AC代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define REP(i,a,b) for(register int i=(a); i<(b); i++)
#define REPE(i,a,b) for(register int i=(a); i<=(b); i++)
#define PERE(i,a,b) for(register int i=(a); i>=(b); i--)
#ifdef sahdsg
#define DBG(...) printf(__VA_ARGS__)
#else
#define DBG(...) void(0)
#endif
typedef long long ll;
struct node {
ll x, l, r, v;
inline bool operator<(const node&r) const {
return x<r.x || (x==r.x && v>r.v);
}
};
#define MAXN 20007
node l0g[MAXN]; int l0gn;
ll ity[MAXN], ny=0;
inline int yti(ll y) {
return lower_bound(ity,ity+ny,y)-ity+1;
}
struct St {
int v; int dt;
};
St st[MAXN<<2];
void build(int p, int l, int r) {
st[p].v=0, st[p].dt=0;
if(r>l) {
int m=(l+r)>>1;
build(p*2, l, m);
build(p*2+1, m+1, r);
}
}
int L; int R;
inline void spread(int p) {
st[p*2].v+=st[p].dt;
st[p*2+1].v+=st[p].dt;
st[p*2].dt+=st[p].dt;
st[p*2+1].dt+=st[p].dt;
st[p].dt=0;
}
void opa(int p, int l, int r, int v) {
if(l>=L && r<=R) {
st[p].dt += v;
st[p].v+=v;
return;
}
spread(p);
int m=(l+r)>>1;
if(m>=L) opa(p*2, l, m, v);
if(m+1<=R) opa(p*2+1, m+1, r, v);
st[p].v = max(st[p*2].v, st[p*2+1].v);
}
int opq(int p, int l, int r) {
if(l>=L && r<=R) {
return st[p].v;
}
spread(p);
int m=(l+r)>>1;
int ans=0;
if(m>=L) ans = max(ans, opq(p,l,m));
if(m+1<=R) ans = max(ans, opq(p*2+1,m+1,r));
return ans;
}
int main() {
int n,W,H;
while(~scanf("%d%d%d", &n, &W, &H)) {
ny=0;
l0gn=0;
REP(i,0,n) {
int t=i<<1, c;
ll x,y; scanf("%lld%lld%d", &x, &y, &c);
l0g[t].v=c; l0g[t|1].v=-c;
l0g[t].x=x; l0g[t|1].x=x+W-1;
l0g[t].l= l0g[t|1].l=y; ity[ny++]=y;
l0g[t].r= l0g[t|1].r=y+H-1; ity[ny++]=y+H-1;
}
sort(l0g,l0g+n+n);
sort(ity,ity+ny); ny = unique(ity,ity+ny)-ity;
build(1,1,ny);
int ans=0;
REP(i,0,n+n) {
L=yti(l0g[i].l), R=yti(l0g[i].r);
opa(1, 1, ny, l0g[i].v);
L=1, R=ny;
ans = max(ans, opq(1, 1, ny));
}
printf("%d
", ans);
}
return 0;
}