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\n",dis[i]);
return 0;
}