BZOJ 1218: [HNOI2003]激光炸弹

Description

一个长度为R的正方形能圈住的最大点权。

Solution

扫描线.

可以将一个点转化成矩形,让覆盖它的矩形左上角在这个范围内时可以覆盖这个点。

然后就变成了若干个矩形求一个点的最大点权了,然后扫描线搞一搞...

Code

/**************************************************************
    Problem: 1218
    User: BeiYu
    Language: C++
    Result: Accepted
    Time:152 ms
    Memory:9144 kb
****************************************************************/
 
#include <bits/stdc++.h>
using namespace std;
 
#define mpr make_pair
 
typedef pair<int,int> pr;
const int N = 100500;
const int M = 5050;
 
inline int in(int x=0,char s=getchar(),int v=1) { while(s>'9'||s<'0')v=s=='-'?-1:v,s=getchar();
    while(s>='0'&&s<='9')x=x*10+s-'0',s=getchar();return x*v; }
 
int n,r,cp,ans;
int xx[N],yy[N];
struct S { int x,y1,y2,w,f; }t[N<<1];
 
int cmpx(const S &a,const S &b) { return a.x==b.x?a.f>b.f:a.x<b.x; }
 
namespace Seg {
    int mx[N<<2],tg[N<<2];
     
    #define lc (o<<1)
    #define rc (o<<1|1)
    #define mid ((l+r)>>1)
     
    void T(int o,int v) { tg[o]+=v,mx[o]+=v; }
    void Push(int o,int l,int r) {
        if(l==r) return;
        if(tg[o]) T(lc,tg[o]),T(rc,tg[o]),tg[o]=0;
    }
    void Update(int o) { mx[o]=max(mx[lc],mx[rc]); }
    void Add(int o,int l,int r,int L,int R,int v) {
        Push(o,l,r);
        if(L<=l && r<=R) { T(o,v);return; }
        if(L<=mid) Add(lc,l,mid,L,R,v);
        if(R>mid) Add(rc,mid+1,r,L,R,v);
        Update(o);
    }
    int Qur(int o,int l,int r,int L,int R) {
        Push(o,l,r);
        if(L<=l && r<=R) return mx[o];
        int res=0;
        if(L<=mid) res=max(res,Qur(lc,l,mid,L,R));
        if(R>mid) res=max(res,Qur(rc,mid+1,r,L,R));
        return res;
    }
}
 
int main() {
    n=in(),r=in();
    if(r<=0) return puts("0"),0;
    for(int i=1;i<=n;i++) {
        int x=in()+1,y=in()+1,z=in();
        t[++cp]=(S) { x+1,y+1,y+r,z,1 };
        t[++cp]=(S) { x+r,y+1,y+r,z,-1 };
    }
    sort(t,t+cp+1,cmpx);
    for(int i=1,j,k;i<=cp;i=j+1) {
        int x=t[i].x;
        for(j=i;j+1<=cp && x==t[j+1].x;j++);
        for(k=i;k<=j && t[k].f>0;k++)
            Seg::Add(1,1,M,t[k].y1,t[k].y2,t[k].w);
        ans=max(ans,Seg::Qur(1,1,M,1,M));
        for(;k<=j;k++) Seg::Add(1,1,M,t[k].y1,t[k].y2,-t[k].w);
    }
    printf("%d
",ans);
    return 0;
}

  

原文地址:https://www.cnblogs.com/beiyuoi/p/6748509.html