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