题目链接:http://poj.org/problem?id=2482
题意:给你一个矩形,让你求出矩形在某一个位置时 点的权值和最大(不包括边界)
if(l + 1 == r) return ;
建边方法
ss[++laz_ss] = seg(x, x + w, y, c);
ss[++laz_ss] = seg(x, x + w, y + h,-c);
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%lld%lld",&x,&y)
#define RD3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)
typedef long long ll;
const int MAXN=88000+5;//因为点有1W个,所以扫描线2W个,不同的Y坐标最多有2W个
int laz[MAXN],sum[MAXN];
ll L[MAXN], R[MAXN];
ll X[MAXN];
struct seg
{
ll l,r,h;
ll d;
seg(){}
seg(ll a,ll b,ll c,ll d):l(a),r(b),h(c),d(d){}
bool operator <(const seg&b)const
{
if(h == b.h) return d<b.d;
return h<b.h;
}
}ss[MAXN];
void PushUp(int i)
{
sum[i]=max(sum[i*2], sum[i*2+1]) ;
}
void pushdown(int i)
{
if(laz[i]!=0)
{
sum[i << 1] += laz[i];
sum[i << 1 | 1] += laz[i];
laz[i << 1] += laz[i];
laz[i << 1 | 1] += laz[i];
laz[i] = 0;
}
}
void build(int l, int r, int cur){
L[cur] = X[l];
R[cur] = X[r];
sum[cur] = 0;
laz[cur] = 0;
if(l + 1 == r)return ;
int mid = l + r >> 1;
build(l, mid, cur << 1);
build(mid, r, cur << 1 | 1);
}
void update(ll ql,ll qr,ll v,int i)
{
if(ql<=L[i] && R[i]<=qr)
{
laz[i]+=v;
sum[i]+=v;
return ;
}
pushdown(i);
if(ql < R[i << 1]) update(ql,qr,v,i << 1);
if(qr > L[i << 1 | 1]) update(ql,qr,v,i << 1 | 1);
PushUp(i);
}
int main()
{
int n;
ll w,h;
while(~RD(n))
{
RD2(w, h);
ll x, y, c;
int laz_x=0,laz_ss=0;//记录有多少个Y值和扫描线
for(int i=1;i<=n;i++)
{
RD3(x, y, c);
ss[++laz_ss] = seg(x, x + w, y, c);
ss[++laz_ss] = seg(x, x + w, y + h,-c);
X[++laz_x] = x;
X[++laz_x] = x + w;
}
sort(ss+1,ss+laz_ss+1);
sort(X+1,X+laz_x+1);
laz_x = unique(X+1,X+1+laz_x)-X-1;
int ans=0;
build(1, laz_x, 1);
for(int i=1;i<=laz_ss;i++) {
update(ss[i].l, ss[i].r, ss[i].d,1);
ans=max(ans,sum[1]);
}
printf("%d\n",ans);
}
}