ZOJ 3525 Disappearance(扫描线)

题意:有三维的空间里有N个点(N<5000),要求用一个长方体LB*LW*LH去包围一些点,使得长方体内的点的权值和最小。

因为N只有5000,起先我们的方法是暴力去枚举两维,即按X排序,找出点彼此间距离不超过LB的点,然后将这些点按Y排序,在线段树中放进Y之间最大距离不超过LW的点。。但是这样死活过不了。。最后枚举一维,直接按X排序,然后就是poj 2482的做法了。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
const int N=5005;

int n;
int LB,LW,LH;

struct REC
{
    int x,y,z,w;
    REC(){}
    REC(int x,int y,int z,int w) :
        x(x),y(y),z(z),w(w) {}
    bool operator<(const REC &B)const
    {
        return x<B.x;
    }
};
struct Line
{
    int x,y1,y2,w;
    Line(){}
    Line(int x,int y1,int y2,int w) :
        x(x),y1(y1),y2(y2),w(w) {}
    bool operator<(const Line &B)const
    {
        return x<B.x||(x==B.x&&w>B.w);
    }
};

vector<REC> rec;
vector<Line> line;

struct Segtree
{
    int mx[N*4],delay[N*4];
    void fun(int ind,int valu)
    {
        mx[ind]+=valu; delay[ind]+=valu;
    }
    void PushDown(int ind)
    {
        if(delay[ind])
        {
            fun(LL(ind),delay[ind]);
            fun(RR(ind),delay[ind]);
            delay[ind]=0;
        }
    }
    void PushUp(int ind)
    {
        mx[ind]=max(mx[LL(ind)],mx[RR(ind)]);
    }
    void build(int lft,int rht,int ind)
    {
        mx[ind]=delay[ind]=0;
        if(lft!=rht)
        {
            int mid=MID(lft,rht);
            build(lft,mid,LL(ind));
            build(mid+1,rht,RR(ind));
        }
    }
    void updata(int st,int ed,int valu,int lft,int rht,int ind)
    {
        if(st<=lft&&rht<=ed) fun(ind,valu);
        else
        {
            PushDown(ind);
            int mid=MID(lft,rht);
            if(st<=mid) updata(st,ed,valu,lft,mid,LL(ind));
            if(ed> mid) updata(st,ed,valu,mid+1,rht,RR(ind));
            PushUp(ind);
        }
    }
}seg;
int calc(int st,int ed)
{
    line.clear();
    for(int i=st;i<=ed;i++)
    {
        int y=rec[i].y;
        int z=rec[i].z;
        int w=rec[i].w;

        line.push_back(Line(y,z,z+LH,w));
        line.push_back(Line(y+LW,z,z+LH,-w));
    }
    sort(line.begin(),line.end());

    seg.build(0,N,1);
    int len=(int)line.size(),mx=0;
    for(int i=0;i<len;i++)
    {
        seg.updata(line[i].y1,line[i].y2,line[i].w,0,N,1);
        mx=max(mx,seg.mx[1]);
    }
    return mx;
}
int main()
{
   // freopen("in.txt","r",stdin);

    while(scanf("%d",&n)!=EOF)
    {
        rec.clear(); line.clear();
        for(int i=0;i<n;i++)
        {
            int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d);
            if(d>=0) continue;
            a+=1000; b+=1000; c+=1000;
            rec.push_back(REC(a,b,c,-d));
        }

        scanf("%d%d%d",&LB,&LW,&LH);

        if(rec.size()==0)
        {
            puts("Error 404, mahou shoujo not found!");
            continue;
        }

        n=(int)rec.size();
        sort(rec.begin(),rec.end());

        int ind1=0,ind2=0,mx=0;
        while(ind1<n)
        {
            while(ind2<n&&rec[ind2].x-rec[ind1].x<=LB) ind2++;
            mx=max(mx,calc(ind1,ind2-1));
            if(ind2==n) break;
            while(ind1+1<n&&rec[ind1].x==rec[ind1+1].x) ind1++;
            ind1++;
        }
        printf("%d\n",-mx);
    }
    return 0;
}

死活过不了的做法。。贴出来,说不定以后想到哪里挂了。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
const int N=5005;

struct REC
{
    int x,y,z,w;
    REC(){}
    REC(int x,int y,int z,int w) :
        x(x),y(y),z(z),w(w) {}
    void print()
    {
        cout<<x<<" "<<y<<" "<<z<<" "<<w<<endl;
    }
};
bool cmpX(const REC &A,const REC &B)
{
    return A.x<B.x;
}
bool cmpY(const REC &A,const REC &B)
{
    return A.y<B.y;
}

int n,LB,LW,LH,ans;
vector<REC> rec;
vector<REC> order;

struct Segtree
{
    int mx[N*4],delay[N*4];
    void PushUp(int ind)
    {
        mx[ind]=max(mx[LL(ind)],mx[RR(ind)]);
    }
    void fun(int ind,int valu)
    {
        mx[ind]+=valu;
        delay[ind]+=valu;
    }
    void PushDown(int ind)
    {
        if(delay[ind])
        {
            fun(LL(ind),delay[ind]);
            fun(RR(ind),delay[ind]);
            delay[ind]=0;
        }
    }
    void build(int lft,int rht,int ind)
    {
        mx[ind]=delay[ind]=0;

        if(lft!=rht)
        {
            int mid=MID(lft,rht);
            build(lft,mid,LL(ind));
            build(mid+1,rht,RR(ind));
        }
    }
    void updata(int st,int ed,int valu,int lft,int rht,int ind)
    {
        if(st<=lft&&rht<=ed) fun(ind,valu);
        else
        {
            PushDown(ind);
            int mid=MID(lft,rht);
            if(st<=mid) updata(st,ed,valu,lft,mid,LL(ind));
            if(ed> mid) updata(st,ed,valu,mid+1,rht,RR(ind));
            PushUp(ind);
        }
    }
}seg;

void fun(int st,int ed)
{
    seg.build(0,N,1);
	order.clear();

    for(int i=st;i<=ed;i++) order.push_back(rec[i]);
    sort(order.begin(),order.end(),cmpY);

    int len=(int)order.size();
    int ind1=0,ind2=0;

    while(ind1<len)
    {
        int y1=order[ind1].y;
        int z1=order[ind1].z;
        int w1=order[ind1].w;
        while(ind2<len)
        {
            int y2=order[ind2].y;
            int z2=order[ind2].z;
            int w2=order[ind2].w;
            if(y2-y1<=LW)
            {
                seg.updata(z2,z2+LH,w2,0,N,1);
                ans=max(ans,seg.mx[1]);
                ind2++;
            }
            else break;
        }
        seg.updata(z1,z1+LH,-w1,0,N,1);
        ans=max(ans,seg.mx[1]);
        ind1++;
    }
}


int main()
{
    //freopen("in.txt","r",stdin);

    while(scanf("%d",&n)!=EOF)
    {
        ans=0;
        rec.clear();  order.clear();

        for(int i=0;i<n;i++)
        {
            int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d);
            if(d>=0) continue;
            a+=1000; b+=1000; c+=1000;
            rec.push_back(REC(a,b,c,-d));
        }

        scanf("%d%d%d",&LB,&LW,&LH);

        if(rec.size()==0)
        {
            puts("Error 404, mahou shoujo not found!");
            continue;
        }

        sort(rec.begin(),rec.end(),cmpX);

        int ind1=0,ind2=0;
        while(ind1<n)
        {
            while(ind2<n&&rec[ind2].x-rec[ind1].x<=LB) ind2++;
            fun(ind1,ind2);
            while(ind1+1<n&&rec[ind1].x==rec[ind1+1].x) ind1++;
            ind1++;
        }
        printf("%d\n",-ans);
    }
    return 0;
}



你可能感兴趣的:(ZOJ 3525 Disappearance(扫描线))