传送门
n2n^2n2暴力显然,考虑优化。
有一种想法是使用四分树/kd-tree/树套树,发现你并不能得到100pts100pts100pts的好成绩(空间会炸掉)
考试的时候比较智熄,先暴力四分树建边然后跑dijkstra,于是动态内存炸了。。。88pts88pts88pts滚粗。
那剩下那12pts12pts12pts如何拿呢?
我们考虑只用四分树加入点,这样的空间开销仅有O(nlogn)O(nlog_n)O(nlogn​),然后把一个点到一个矩形的边存下来,每次跑dijkstradijkstradijkstra的时候暴力在四分树上找被松弛的点把它们松弛之后加入堆即可。
88pts88pts88pts代码:

#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
#define x1 ldxx1
#define x2 ldxx2
#define y1 ldxy1
#define y2 ldxy2
using namespace std;
const int rlen=1<<18|1;
inline char gc(){static char buf[rlen],*ib,*ob;(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));return ib==ob?-1:*ib++;
}
inline int read(){int ans=0;char ch=gc();while(!isdigit(ch))ch=gc();while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();return ans;
}
const int N=70005,M=150005;
typedef pair<int,int> pii;
int pos[N],tot=0;
int son[M*20][4],dis[M*20];
bool in[M*20];
vector<pii>e[N];
int n,W,H,m,rt=0;
const int mogic=1e5+7;
struct Hash_table{vector<int>ori[mogic],val[mogic];inline int query(int x){for(ri t=x%mogic,i=ori[t].size()-1;~i;--i)if(ori[t][i]==x)return val[t][i];return -1;}inline void update(int x,int v){int t=x%mogic;ori[t].push_back(x),val[t].push_back(v);}
}mp;
inline void insert(int&p,int x1,int y1,int x2,int y2,int kx,int ky,int id){if(!p)p=++tot;dis[p]=1e9;if(x1==x2&&y1==y2){mp.update(p,id),pos[id]=p;return;}int mx=x1+x2>>1,my=y1+y2>>1;if(kx<=mx&&ky<=my)insert(son[p][0],x1,y1,mx,my,kx,ky,id);if(kx<=mx&&ky>my)insert(son[p][1],x1,my+1,mx,y2,kx,ky,id);if(kx>mx&&ky<=my)insert(son[p][2],mx+1,y1,x2,my,kx,ky,id);if(kx>mx&&ky>my)insert(son[p][3],mx+1,my+1,x2,y2,kx,ky,id);
}
int ldxid,ldxw,qx1,qx2,qy1,qy2;
int cnt=0,cnt1=0;
inline bool check(int x1,int y1,int x2,int y2){return !((x2<qx1)||(x1>qx2)||(y2<qy1)||(y1>qy2));}
inline void addedge(int p,int x1,int y1,int x2,int y2){++cnt;if(qx1<=x1&&x2<=qx2&&qy1<=y1&&y2<=qy2){e[ldxid].push_back(pii(p,ldxw)),++cnt1;return;}int mx=x1+x2>>1,my=y1+y2>>1;if(son[p][0]&&check(x1,y1,mx,my))addedge(son[p][0],x1,y1,mx,my);if(son[p][1]&&check(x1,my+1,mx,y2))addedge(son[p][1],x1,my+1,mx,y2);if(son[p][2]&&check(mx+1,y1,x2,my))addedge(son[p][2],mx+1,y1,x2,my);if(son[p][3]&&check(mx+1,my+1,x2,y2))addedge(son[p][3],mx+1,my+1,x2,y2);
}
inline void dijkstra(){priority_queue<pii,vector<pii>,greater<pii> >q;q.push(pii(dis[pos[1]]=0,pos[1]));while(!q.empty()){int x=q.top().se;q.pop();if(in[x])continue;in[x]=1;int p=mp.query(x);if(p==-1){for(ri i=0,v;i<4;++i){if(!(v=son[x][i]))continue;if(dis[v]>dis[x])dis[v]=dis[x],q.push(pii(dis[v],v));}}else{for(ri i=0,v,w;i<e[p].size();++i){v=e[p][i].fi,w=e[p][i].se;if(dis[v]>dis[x]+w)dis[v]=dis[x]+w,q.push(pii(dis[v],v));}}}for(ri i=2;i<=n;++i)cout<<dis[pos[i]]<<'\n';
}
int main(){freopen("jump.in","r",stdin);freopen("jump.out","w",stdout);n=read(),m=read(),W=read(),H=read();for(ri i=1,x,y;i<=n;++i){x=read(),y=read();insert(rt,1,1,W,H,x,y,i);}for(ri i=1,w,x1,y1,x2,y2,id;i<=m;++i){ldxid=read(),ldxw=read(),qx1=read(),qx2=read(),qy1=read(),qy2=read();addedge(rt,1,1,W,H);}dijkstra();return 0;
}

100pts100pts100pts代码:

#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
#define x1 ldxx1
#define x2 ldxx2
#define y1 ldxy1
#define y2 ldxy2
using namespace std;
const int rlen=1<<18|1;
inline char gc(){static char buf[rlen],*ib,*ob;(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));return ib==ob?-1:*ib++;
}
inline int read(){int ans=0;char ch=gc();while(!isdigit(ch))ch=gc();while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();return ans;
}
const int N=70005,M=150005;
typedef pair<int,int> pii;
int tot=0;
int son[M*20][4],dis[M*20];
bool in[M*20];
vector<int>e[M*20];
vector<int>g[N];
int n,W,H,m,rt=0;
inline void insert(int&p,int x1,int y1,int x2,int y2,int kx,int ky,int id){if(!p)p=++tot;dis[p]=1e9;if(x1==x2&&y1==y2){e[p].push_back(id);return;}int mx=x1+x2>>1,my=y1+y2>>1;if(kx<=mx&&ky<=my)insert(son[p][0],x1,y1,mx,my,kx,ky,id);if(kx<=mx&&ky>my)insert(son[p][1],x1,my+1,mx,y2,kx,ky,id);if(kx>mx&&ky<=my)insert(son[p][2],mx+1,y1,x2,my,kx,ky,id);if(kx>mx&&ky>my)insert(son[p][3],mx+1,my+1,x2,y2,kx,ky,id);
}
int pos[M],val[M],qx1[M],qx2[M],qy1[M],qy2[M];
priority_queue<pii,vector<pii>,greater<pii> >q;
inline bool check(int x1,int y1,int x2,int y2,int id){return !((x2<qx1[id])||(x1>qx2[id])||(y2<qy1[id])||(y1>qy2[id]));}
inline void build(int p){if(!p)return;for(ri i=0;i<4;++i){if(!son[p][i])continue;e[p].push_back(son[p][i]);build(son[p][i]);}
}
inline void addedge(int p,int x1,int y1,int x2,int y2,int id){if(!p||dis[p]<=dis[pos[id]]+val[id])return;if(qx1[id]<=x1&&x2<=qx2[id]&&qy1[id]<=y1&&y2<=qy2[id]){q.push(pii(dis[p]=dis[pos[id]]+val[id],p));return;}int mx=x1+x2>>1,my=y1+y2>>1;if(son[p][0]&&check(x1,y1,mx,my,id))addedge(son[p][0],x1,y1,mx,my,id);if(son[p][1]&&check(x1,my+1,mx,y2,id))addedge(son[p][1],x1,my+1,mx,y2,id);if(son[p][2]&&check(mx+1,y1,x2,my,id))addedge(son[p][2],mx+1,y1,x2,my,id);if(son[p][3]&&check(mx+1,my+1,x2,y2,id))addedge(son[p][3],mx+1,my+1,x2,y2,id);
}
inline void dijkstra(){q.push(pii(dis[1]=0,1));while(!q.empty()){int x=q.top().se;q.pop();if(in[x])continue;in[x]=1;if(x<=n)for(ri i=0;i<g[x].size();++i)addedge(rt,1,1,W,H,g[x][i]);else{for(ri i=0,v,w;i<e[x].size();++i){v=e[x][i];if(dis[v]>dis[x])q.push(pii(dis[v]=dis[x],v));}}}for(ri i=2;i<=n;++i)cout<<dis[i]<<'\n';
}
int main(){freopen("jump.in","r",stdin);freopen("jump.out","w",stdout);n=read(),m=read(),W=read(),H=read();tot=n;for(ri i=1,x,y;i<=n;++i){dis[i]=1e9;x=read(),y=read();insert(rt,1,1,W,H,x,y,i);}for(ri i=1,w,x1,y1,x2,y2,id;i<=m;++i){pos[i]=read(),val[i]=read(),qx1[i]=read(),qx2[i]=read(),qy1[i]=read(),qy2[i]=read();g[pos[i]].push_back(i);}build(rt);dijkstra();return 0;
}

LOJ#3159. 「NOI2019」弹跳(四分树+dijkstra)相关推荐

  1. LOJ 3156: 「NOI2019」回家路线

    题目传送门:LOJ #3156. 题意简述: 有一张 \(n\) 个点 \(m\) 条边的有向图,边有两个权值 \(p_i\) 和 \(q_i\)(\(p_i<q_i\))表示若 \(p_i\) ...

  2. LOJ#3156. 「NOI2019」回家路线(前缀和优化建图+for循环+凸包)

    传送门 来一发大常数做法(然而网络赛的时候凸包插点的方向写反了...40pts40pts40pts滚了什么我居然还有40) 对于一条边(u,v,p,q)(u,v,p,q)(u,v,p,q),我们把二元 ...

  3. Loj #2983. 「WC2019」数树

    Loj #2983. 「WC2019」数树 题目背景 白兔喜欢树. 白云喜欢数数. 有 \(n\) 只鼠,白兔用 \(n − 1\) 根蓝色绳子把它们连成了一棵树,每根蓝色绳子连着两只鼠,白云用 \( ...

  4. Loj #3111. 「SDOI2019」染色

    Loj #3111. 「SDOI2019」染色 题目描述 给定 \(2 \times n\) 的格点图.其中一些结点有着已知的颜色,其余的结点还没有被染色.一个合法的染色方案不允许相邻结点有相同的染色 ...

  5. Loj #3055. 「HNOI2019」JOJO

    Loj #3055. 「HNOI2019」JOJO JOJO 的奇幻冒险是一部非常火的漫画.漫画中的男主角经常喜欢连续喊很多的「欧拉」或者「木大」. 为了防止字太多挡住漫画内容,现在打算在新的漫画中用 ...

  6. LOJ#2230. 「BJOI2014」大融合

    LOJ#2230. 「BJOI2014」大融合 题目描述 小强要在$N$个孤立的星球上建立起一套通信系统.这套通信系统就是连接$N$个点的一个树.这个树的边是一条一条添加上去的. 在某个时刻,一条边的 ...

  7. Loj #2568. 「APIO2016」烟花表演

    Loj #2568. 「APIO2016」烟花表演 题目描述 烟花表演是最引人注目的节日活动之一.在表演中,所有的烟花必须同时爆炸.为了确保安全,烟花被安置在远离开关的位置上,通过一些导火索与开关相连 ...

  8. Loj #2554. 「CTSC2018」青蕈领主

    Loj #2554. 「CTSC2018」青蕈领主 题目描述 "也许,我的生命也已经如同风中残烛了吧."小绿如是说. 小绿同学因为微积分这门课,对"连续"这一概 ...

  9. loj#2143. 「SHOI2017」组合数问题

    loj#2143. 「SHOI2017」组合数问题 题目描述 Solution 考虑转化一下我们要求的东西. ∑i=0n(nkik+r)=∑i=0n(nki)[i≡r(modk)]\sum_{i=0} ...

最新文章

  1. 完善的仿京东电商开源项目
  2. python职能-最受欢迎的10家互联网公司揭秘Python薪资!
  3. 区块链基础知识系列 第三课 区块链中的默克尔树
  4. win2012活动目录介绍
  5. 在Spring中使用Netflix Hystrix批注
  6. 程序员如何应对中年危机?让编程变得不再重要
  7. nosuiteable Oracle,快给你的Kubernetes集群建一个只读账户(防止高管。。。后)
  8. Linux先发送条件变量,linux 条件变量 浅谈Linux条件变量的使用
  9. python操作注册表能干啥_转 python操作注册表模块_winreg
  10. 【Vue2.0】—props 配置(十三)
  11. 热门NPM库 “coa” 和“rc” 接连遭劫持,影响全球的 React 管道
  12. Mysql 定时备份操作
  13. NB-IoT移远BC95使用小结
  14. Kubernets k8s中yml格式与pod yml格式
  15. 3ds max 旋转及角度
  16. ultraos win10启动盘_使用ultraiso软件制Win10专业版U盘系统盘制作安装教程
  17. 将字符串中的特殊字符进行转义
  18. 【Unity3D 问题总结】Unity报错提示:Asset database transaction committed twice
  19. C语言 常用内存函数
  20. NOIP备战题解集(11.10)

热门文章

  1. 半导体的光刻工艺全过程及技术讲解
  2. qt(c++)数组越界编译不会报错
  3. 中国超高分子量聚乙烯产业调研与投资前景报告(2022版)
  4. pd.read_csv用法
  5. Shell中read的用法详解
  6. android通知栏快捷设置开发,即添加快捷磁贴指北
  7. linux设置快捷命令
  8. LINUX VFS分析之五open接口分析与总结
  9. MDI/MDIX/Auto-MDI/MDIX的解析大全
  10. 初中数学的一些压轴题