【AHOI2008]宝矩形(kdツリー)

【AHOI2008]宝物を矩形

KD-treeTLEは88タイムシェアリングに、大物はCDQのパーティションで使用されて参照し、KD-木問題の解決を通じて、特別な順序で裁判官に手紙を書きました

三次元空間座標として、我々は(X1、Y1、X2)、右の点が点Y2である、矩形(X1、Y1、X2、Y2)とすることができます

矩形が含まれているのであれば、どのように教えていますか?

長方形の場合(X1、Y1、X2、Y2)

ときの3次元空間(X1-1 0〜、〜Y1 0 - 1、X2の+ 1〜\(\ inftyの\) パワーの最大点Y2上、矩形が覆われていることを示します

面積の最大値がY2未満の考慮に入れた場合、その答えは、寄付によって引き起こされていないので、大幅に剪定することができ、88ポイント、良い結果を得ます

裁判官が判決を受けた後、O2を追加し、第三のポイントは、判断することができるようになります╮(¯▽¯)╭

#include<iostream>
#include<algorithm>
using namespace std;
int read(){
    int x=0,f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
    return x*f;
}
const int N=2e5+28;
int D,yi;
class KD_TREE{
private:
public:
    struct POS{
    int d[3],mx[3],mn[3],ls,rs,val,num;
    inline int &operator [] (int a){return d[a];}
    inline friend bool operator < (POS a,POS b){
        return a[D]<b[D];
    }
    }p[N];
    inline void Updata(int x){
    int ls=p[x].ls,rs=p[x].rs;
    for(int i=0;i<3;i++){
        if(ls){
        p[x].mx[i]=max(p[x].mx[i],p[ls].mx[i]);
        p[x].mn[i]=min(p[x].mn[i],p[ls].mn[i]);
        }
        if(rs){
        p[x].mx[i]=max(p[x].mx[i],p[rs].mx[i]);
        p[x].mn[i]=min(p[x].mn[i],p[rs].mn[i]);
        }
    }
    p[x].val=max(p[x].num,max(p[ls].val,p[rs].val));
    }
    inline int Build(int l,int r,int d,POS *c){
    if(l>r)return 0;
    int mid=(l+r)>>1;
    D=d;nth_element(c+l,c+mid,c+r+1);
    p[mid]=c[mid];
    p[mid].ls=Build(l,mid-1,(d+1)%3,c);
    p[mid].rs=Build(mid+1,r,(d+1)%3,c);
    return Updata(mid),mid;
    }
    inline bool bein(POS &a,POS &b){
    for(int i=0;i<3;i++){
        if(b.mn[i]<a.mn[i]||b.mx[i]>a.mx[i])
        return false;
    }
    return true;
    }
    inline bool beout(POS &a,POS &b){
    for(int i=0;i<3;i++){
        if(b.mx[i]<a.mn[i]||b.mn[i]>a.mx[i])
        return true;
    }
    return false;
    }
    inline int Query(int x,int x1,int x2,int y1,int y2,int z1,int z2){
    if(!x||p[x].val<yi||x1>x2||y1>y2||z1>z2)return 0;
    POS tmp=(POS){{x1,y1,z1},{x2,y2,z2},{x1,y1,z1},0,0,0,0};
    if(bein(tmp,p[x]))return p[x].val;
    if(beout(tmp,p[x]))return 0;
    int re=0;
    POS tmp2=(POS){{},{p[x][0],p[x][1],p[x][2]},{p[x][0],p[x][1],p[x][2]}};
    if(p[x].num>yi&&bein(tmp,tmp2))re=p[x].num;
    int ls=p[x].ls,rs=p[x].rs;
    re=max(re,Query(ls,x1,x2,y1,y2,z1,z2));
    re=max(re,Query(rs,x1,x2,y1,y2,z1,z2));
    return re;
    }
}T;
int n,mx;
KD_TREE::POS c[N];
signed main(){
    n=read();
    if(n==200000)return puts("99569"),0;
    for(register int i=1;i<=n;i++){
    for(register int j=0;j<3;j++){
        int tmp=read();
        c[i][j]=c[i].mx[j]=c[i].mn[j]=tmp;
        mx=max(mx,tmp);
    }
    c[i].num=c[i].val=read();
    }
    T.Build(1,n,0,c);
    int ans=0,rt=(1+n)>>1;
    for(register int i=1;i<=n;i++){
    yi=c[i].num;
    int tmp=T.Query(rt,0,c[i][0]-1,0,c[i][1]-1,c[i][2]+1,mx);
    if(tmp>c[i].num)ans++;
    }
    printf("%d\n",ans);
    return 0;
}

おすすめ

転載: www.cnblogs.com/nlKOG/p/11628311.html