洛谷P5471/LOJ3159[NOI2019]弹跳

这题主要问题在于卡空间,树套树和kD树都被卡

于是考虑只存点不建边,那么放入$dijkstra$中排序的就是矩形而非点,同时用线段树套set把空间卡到$O(nlogn)$就可以AC了。

#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
using namespace std;
const int N=70005;
char rB[1<<21],*S,*T,wB[1<<21];
int wp=-1;
inline char gc(){return S==T&&(T=(S=rB)+fread(rB,1,1<<21,stdin),S==T)?EOF:*S++;}
inline void flush(){fwrite(wB,1,wp+1,stdout);wp=-1;}
inline void pc(char c){if(wp+1==(1<<21))flush();wB[++wp]=c;}
inline int rd(){
    char c=gc();
    while(c<48||c>57)c=gc();
    int x=c&15;
    for(c=gc();c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c&15);
    return x;
}
short buf[15];
inline void wt(int x){
    short l=-1;
    while(x>9){
        buf[++l]=x%10;
        x/=10;
    }
    pc(x|48);
    while(l>=0)pc(buf[l--]|48);
    pc('\n');
}
int px[N],py[N],d[N],w,h,p,x,y,l,r,ts[N],tl=-1;
struct point{
    int p;
    point(int p):p(p){}
    inline bool operator <(const point &b)const{return py[p]<py[b.p]||py[p]==py[b.p]&&p<b.p;};
};
set<point> sum[N<<2];
struct mat{
    int t,l,r,p,q;
    mat(int t,int l,int r,int p,int q):t(t),l(l),r(r),p(p),q(q){}
};
vector<mat> a[N];
struct node{
    int u,p,d;
    node(){}
    node(int u,int p,int d):u(u),p(p),d(d){}
    inline bool operator <(const node &b)const{return d>b.d;}
};
priority_queue<node> Q;
void add(int o,int L,int R){
    sum[o].insert(point(p));
    if(L<R){
        int lc=o<<1,rc=lc|1,M=L+R>>1;
        if(x<=M)add(lc,L,M);
        else add(rc,M+1,R);
    }
}
void del(int o,int L,int R,int x,int p){
    sum[o].erase(point(p));
    if(L<R){
        int lc=o<<1,rc=lc|1,M=L+R>>1;
        if(x<=M)del(lc,L,M,x,p);
        else del(rc,M+1,R,x,p);
    }
}
inline void work(int o){
    py[0]=x;
    for(set<point>::iterator it=sum[o].lower_bound(point(0));it!=sum[o].end()&&py[it->p]<=y;it++){
        d[it->p]=p;ts[++tl]=it->p;
        for(int i=0;i<a[it->p].size();++i)Q.push(node(it->p,i,p+a[it->p][i].t));
    }
    for(;tl>=0;--tl)del(1,1,w,px[ts[tl]],ts[tl]);
}
void query(int o,int L,int R){
    if(l<=L&&r>=R)work(o);
    else{
        int lc=o<<1,rc=lc|1,M=L+R>>1;
        if(l<=M)query(lc,L,M);
        if(r>M)query(rc,M+1,R);
    }
}
int main(){
    int n=rd(),m=rd(),i,t;
    node u;
    w=rd();h=rd();px[1]=x=rd();py[1]=y=rd();
    for(p=2;p<=n;++p){
        px[p]=x=rd();py[p]=y=rd();
        add(1,1,w);
    }
    while(m--){
        i=rd();t=rd(),l=rd();r=rd();x=rd();y=rd();
        a[i].push_back(mat(t,l,r,x,y));
    }
    memset(d,0x3f,sizeof(d));
    d[1]=0;
    for(i=0;i<a[1].size();++i)Q.push(node(1,i,a[1][i].t));
    while(!Q.empty()){
        u=Q.top();Q.pop();
        l=a[u.u][u.p].l;r=a[u.u][u.p].r;x=a[u.u][u.p].p;y=a[u.u][u.p].q;p=u.d;
        query(1,1,w);
    }
    for(i=2;i<=n;++i)wt(d[i]);
    flush();
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/sunshine-chen/p/11258851.html
今日推荐