p5471 [NOI2019]弹跳

分析

代码

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
const int N = 7e4+300;
const int M = 2e5;
int n,m,w,h,x[N],y[N],p[M],t[M],L[M],R[M],D[M],U[M];
int head[N],nxt[M],cnt,dis[N],vis[N];
multiset<pair<int,int> >d[M*4];
priority_queue<pair<int,int> >q;
inline void update(int le,int ri,int wh,int pl,int id){
    d[wh].insert(mp(y[id],id));
    if(le==ri)return;
    int mid=(le+ri)>>1;
    if(mid>=pl)update(le,mid,wh<<1,pl,id);
      else update(mid+1,ri,wh<<1|1,pl,id);
}
inline void go(int le,int ri,int wh,int id,int k){
    if(le>=L[id]&&ri<=R[id]){
      multiset<pair<int,int> >::iterator it,a;
      it=d[wh].lower_bound(mp(D[id],0));
      while((it!=d[wh].end())&&(it->fi<=U[id])){
          int x=it->se;
          if(!vis[x]){
            vis[x]=1,dis[x]=k;
            for(int i=head[x];i;i=nxt[i])q.push(mp(-k-t[i],i));
        }
          a=it,it++,d[wh].erase(a);
      }
      return;
    }
    int mid=(le+ri)>>1;
    if(mid>=L[id])go(le,mid,wh<<1,id,k);
    if(mid<R[id])go(mid+1,ri,wh<<1|1,id,k);
    return;
}
int main(){
    int i,j,k;
    scanf("%d%d%d%d",&n,&m,&w,&h);
    for(i=1;i<=n;i++){
      scanf("%d%d",&x[i],&y[i]);
      update(1,w,1,x[i],i); 
    }
    for(i=1;i<=m;i++){
      scanf("%d%d%d%d%d%d",&p[i],&t[i],&L[i],&R[i],&D[i],&U[i]);
      nxt[i]=head[p[i]];head[p[i]]=i;
    }
    vis[1]=1;
    for(i=head[1];i;i=nxt[i])q.push(mp(-t[i],i));
    while(!q.empty()){
      int u=q.top().se,v=-q.top().fi;
      q.pop();go(1,w,1,u,v);
    }
    for(i=2;i<=n;i++)printf("%d
",dis[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/yzxverygood/p/11611307.html