luogu P5471 [NOI2019] 바운스

luogu

도트가 직사각형 에지 영역에 연결되기 때문에, 될 수있는심지어 측면 이차원 데이터 구조 최적화하지만이 MLE. 사각형은 데이터 구조의 유지 보수 것입니다 \ (KD-트리 \) , 그래서 고려 \ (KDT \) 최적화도 가장자리, 공간 복잡도 \ (m \ n을-SQRT의 \) ,하지로를

또한, 측면의 복수의 타이틀을 (KDT \) \의 측면에 접속 포인트, 이들 점의 서브 트리이 시점에서 갱신된다. 고려 \ (익스트라 \) 에있어서, 각각의 타임 아웃 \ (DIS \ ) 작은 점 및 업데이트 다른 점, 그리고 다른 사이트는 현재 가장 작은 경우는 찾을 수 있습니다 \ (dis_x + w_i \) 더 이상 업데이트되지 업데이트, 그래서 우리가 할 수있는 모든 시간 초과 최소 \ (dis_x + w_i \ ) , 다음 폭력 업데이트 \ (X의 \) 뿐만 아니라 하위 트리로 어떤 점에서에 해당하는 다음이 삭제되므로 포인트 확산과 총 수는 있습니다 삭제할 \) \ (O (n)이 시간, 그것은 수행 할 수 있습니다 공간 \ (O (N-) \) , 시간 \ (O (m + mlogn \ N SQRT) \)

#include<bits/stdc++.h>
#define LL long long
#define uLL unsigned long long
#define db double

using namespace std;
const int N=70000+10,M=150000+10,inf=2109876543;
int rd()
{
    int x=0,w=1;char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*w;
}
int n,m,di[N],ii=0,e[M][5];
bool cmp(int aa,int bb){return e[aa][0]<e[bb][0];}
vector<int> ee[N];
vector<int>::iterator it[N];
struct node
{
    int x[2],i;
    bool operator < (const node &bb) const {return x[ii]!=bb.x[ii]?x[ii]<bb.x[ii]:x[ii^1]<bb.x[ii^1];} 
}a[N],b[N];
int lx[N],rx[N],ly[N],ry[N],fa[N],sz[N],ch[N][2],rt;
bool ban[N];
int bui(int l,int r)
{
    if(l>r) return 0;
    int mid=(l+r)>>1;
    nth_element(b+l,b+mid,b+r+1);
    int x=b[mid].i,ndd=ii^1;
    sz[x]=1;
    ii=ndd,ch[x][0]=bui(l,mid-1),fa[ch[x][0]]=x,sz[x]+=sz[ch[x][0]];
    ii=ndd,ch[x][1]=bui(mid+1,r),fa[ch[x][1]]=x,sz[x]+=sz[ch[x][1]];
    lx[x]=min(a[x].x[0],min(lx[ch[x][0]],lx[ch[x][1]]));
    rx[x]=max(a[x].x[0],max(rx[ch[x][0]],rx[ch[x][1]]));
    ly[x]=min(a[x].x[1],min(ly[ch[x][0]],ly[ch[x][1]]));
    ry[x]=max(a[x].x[1],max(ry[ch[x][0]],ry[ch[x][1]]));
    return x;
}
struct dj
{
    int x,d;
    bool operator < (const dj &bb) const {return d>bb.d;}
};
priority_queue<dj> q2;
void updd(int x,int i,int ndi)
{
    if(!sz[x]||rx[x]<e[i][1]||lx[x]>e[i][2]||ry[x]<e[i][3]||ly[x]>e[i][4]) return;
    if(lx[x]>=e[i][1]&&rx[x]<=e[i][2]&&ly[x]>=e[i][3]&&ry[x]<=e[i][4]&&di[x]>ndi)
    {
        di[x]=ndi;
        ban[x]=1;
        int xx=x;
        while(xx) --sz[xx],xx=fa[xx];
        if(it[x]!=ee[x].end()) q2.push((dj){x,di[x]+e[*it[x]][0]});
    }
    else if(a[x].x[0]>=e[i][1]&&a[x].x[0]<=e[i][2]&&a[x].x[1]>=e[i][3]&&a[x].x[1]<=e[i][4]&&di[x]>ndi)
    {
        di[x]=ndi;
        ban[x]=1;
        int xx=x;
        while(xx) --sz[xx],xx=fa[xx];
        if(it[x]!=ee[x].end()) q2.push((dj){x,di[x]+e[*it[x]][0]});
    }
    updd(ch[x][0],i,ndi);
    updd(ch[x][1],i,ndi);
}

int main()
{
    n=rd(),m=rd(),rd(),rd();
    for(int i=1;i<=n;++i)
    {
        a[i].x[0]=rd(),a[i].x[1]=rd(),a[i].i=i;
        b[i]=a[i],di[i]=inf;
    }
    lx[0]=ly[0]=inf,rx[0]=ry[0]=-1;
    rt=bui(2,n);
    for(int i=1;i<=m;++i)
    {
        ee[rd()].push_back(i);
        for(int j=0;j<=4;++j)
            e[i][j]=rd();
    }
    for(int i=1;i<=n;++i)
        sort(ee[i].begin(),ee[i].end(),cmp),it[i]=ee[i].begin();
    q2.push((dj){1,(di[1]=0)+e[*it[1]][0]});
    while(!q2.empty())
    {
        int x=q2.top().x;
        q2.pop();
        updd(rt,*it[x],di[x]+e[*it[x]][0]);
        if((++it[x])!=ee[x].end()) q2.push((dj){x,di[x]+e[*it[x]][0]});
    }
    for(int i=2;i<=n;++i) printf("%d\n",di[i]);
    return 0;
}

추천

출처www.cnblogs.com/smyjr/p/11621038.html