线段树+离散化+扫描线
AC之后,又认真读了一遍题目,好文章。
#include<cstdio> #include<map> #include<algorithm> using namespace std; const int maxn=100000+10; int n; long long W,H; long long x[maxn],y[maxn],v[maxn]; struct seg { long long X; long long Y1,Y2; long long val; }s[2*maxn]; struct SegTree { long long MAX; long long add; }segTree[4*maxn]; map<long long,int>m; long long M[maxn]; int k; bool cmp(const seg&a,const seg&b) { if(a.X==b.X) return a.val>b.val; return a.X<b.X; } void pushUp(int rt) { segTree[rt].MAX=max(segTree[2*rt].MAX,segTree[2*rt+1].MAX); } void pushDown(int rt) { if(segTree[rt].add) { segTree[2*rt].add+=segTree[rt].add; segTree[2*rt+1].add+=segTree[rt].add; segTree[2*rt].MAX+=segTree[rt].add; segTree[2*rt+1].MAX+=segTree[rt].add; segTree[rt].add=0; } } void build(int l,int r,int rt) { segTree[rt].add=0; segTree[rt].MAX=0; if(l==r) return; int m=(l+r)/2; build(l,m,2*rt); build(m+1,r,2*rt+1); } void update(long long val,int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) { segTree[rt].add+=val; segTree[rt].MAX+=val; return; } pushDown(rt); int m=(l+r)/2; if(L<=m) update(val,L,R,l,m,2*rt); if(R>m) update(val,L,R,m+1,r,2*rt+1); pushUp(rt); } void lsh() { m.clear(); k=0; for(int i=1;i<=n;i++) { if(m[y[i]]==0) { m[y[i]]=1; M[k++]=y[i]; } if(m[y[i]+H-1]==0) { m[y[i]+H-1]=1; M[k++]=y[i]+H-1; } } sort(M,M+k); //m.clear(); 这个地方比较奇葩。清空了会TLE。。。。 for(int i=0;i<k;i++) m[M[i]]=i+1; } int main() { //freopen("F:\in.txt","r",stdin); while(~scanf("%d%lld%lld",&n,&W,&H)) { for(int i=1;i<=n;i++) scanf("%lld%lld%lld",&x[i],&y[i],&v[i]); lsh(); int tot=0; for(int i=1;i<=n;i++) { s[tot].X=x[i]; s[tot].Y1=m[y[i]]; s[tot].Y2=m[y[i]+H-1]; s[tot].val=v[i]; tot++; s[tot].X=x[i]+W-1; s[tot].Y1=m[y[i]]; s[tot].Y2=m[y[i]+H-1]; s[tot].val=-v[i]; tot++; } sort(s,s+tot,cmp); build(1,k,1); long long max_val=0; for(int i=0;i<tot;i++) { update(s[i].val,s[i].Y1,s[i].Y2,1,k,1); max_val=max(segTree[1].MAX,max_val); } printf("%lld ",max_val); } return 0; }