题目

边权均为2的幂次的无向图,求 \(S\) 到 \(T\) 的最短路

\(n,m\leq 10^5\)


分析

最短路直接考虑用 Dijkstra,它需要维护松弛操作和堆,

那么也就是要重载加号和小于号,而数字可以在主席树上维护。

对于小于号,最直接的一种做法就是从高位到低位找到第一个不同数字的位比较大小,

那么就是先在主席树上二分找到这两个数的LCP,然后比较下一位的大小,

LCP可以用哈希来维护,如果 \(base=2,mod=10^9+7\),顺便就可以把答案求出来,那么就是一个 \(\log\) 的。

对于加号,找到从第x位起第一个0,然后把左边的1都变成0,只把那个0的位置变成1,

这个维护区间左端点为开头极长的1也可以做到一个 \(\log\)

再加上堆的时间复杂度就是 \(O(m\log n\log mx+m\log mx)\)


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
const int mod=1000000007,N=100021; struct node{int y,w,next;}e[N<<1];
int two[N+11],pre[N],n,m,ans,as[N],S,T,rt[N],et=1,st[N],Top,v[N];
int w[N<<6],ls[N<<6],rs[N<<6],len[N<<6],cnt,Cnt; pair<int,int>heap[N<<1];
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void build(int &rt,int l,int r){
rt=++cnt;
if (l==r) return;
int mid=(l+r)>>1;
build(ls[rt],l,mid);
build(rs[rt],mid+1,r);
}
bool geq(int fi,int se,int l,int r){
if (w[fi]==w[se]) return 0;
if (l==r) return w[fi]>w[se];
int mid=(l+r)>>1;
if (w[rs[fi]]==w[rs[se]]) return geq(ls[fi],ls[se],l,mid);
else return geq(rs[fi],rs[se],mid+1,r);
}
int zero(int rt,int l,int r,int x,int y){
if (l==x&&r==y){
if (len[rt]==r-l+1) return 0x3f3f3f3f;
else return l+len[rt];
}
int mid=(l+r)>>1;
if (y<=mid) return zero(ls[rt],l,mid,x,y);
else if (x>mid) return zero(rs[rt],mid+1,r,x,y);
else{
int now=zero(ls[rt],l,mid,x,mid);
if (now!=0x3f3f3f3f) return now;
else return zero(rs[rt],mid+1,r,mid+1,y);
}
}
void upd(int &rt,int l,int r,int x){
int trt=++cnt;
ls[trt]=ls[rt],rs[trt]=rs[rt],rt=trt;
if (l==r){
len[rt]=w[rt]=1;
return;
}
int mid=(l+r)>>1;
if (x<=mid) upd(ls[rt],l,mid,x);
else upd(rs[rt],mid+1,r,x);
w[rt]=(w[ls[rt]]+1ll*w[rs[rt]]*two[mid-l+1]%mod)%mod;
if (len[ls[rt]]==mid-l+1) len[rt]=len[ls[rt]]+len[rs[rt]];
else len[rt]=len[ls[rt]];
}
void update(int &rt,int Rt,int l,int r,int x,int y){
if (l==x&&r==y) {rt=Rt; return;}
else{
int trt=++cnt;
ls[trt]=ls[rt],rs[trt]=rs[rt],rt=trt;
}
int mid=(l+r)>>1;
if (y<=mid) update(ls[rt],ls[Rt],l,mid,x,y);
else if (x>mid) update(rs[rt],rs[Rt],mid+1,r,x,y);
else{
update(ls[rt],ls[Rt],l,mid,x,mid);
update(rs[rt],rs[Rt],mid+1,r,mid+1,y);
}
w[rt]=(w[ls[rt]]+1ll*w[rs[rt]]*two[mid-l+1]%mod)%mod;
if (len[ls[rt]]==mid-l+1) len[rt]=len[ls[rt]]+len[rs[rt]];
else len[rt]=len[ls[rt]];
}
void add(int &Rt,int x){
int now=zero(Rt,0,N,x,N);
upd(Rt,0,N,now);
if (x<now) update(Rt,rt[S],0,N,x,now-1);
}
void Pop(){
heap[1]=heap[Cnt--];
for (int x=1;(x<<1)<=Cnt;){
int y=x<<1|1;
if (y>Cnt||geq(heap[y].first,heap[y-1].first,0,N)) --y;
if (geq(heap[x].first,heap[y].first,0,N)) swap(heap[x],heap[y]),x=y;
else break;
}
}
void Push(pair<int,int> x){
heap[++Cnt]=x;
for (int x=Cnt;x>1;x>>=1)
if (geq(heap[x>>1].first,heap[x].first,0,N))
swap(heap[x],heap[x>>1]);
else break;
}
void Dijkstra(int S){
heap[Cnt=1]=make_pair(rt[S],S),build(rt[S],0,N);
while (Cnt){
while (Cnt&&v[heap[1].second]) Pop();
if (!Cnt) return;
int x=heap[1].second; v[x]=1,Pop();
for (int i=as[x],Rt;i;i=e[i].next)
if (!v[e[i].y]){
int CNT=cnt;
add(Rt=rt[x],e[i].w);
if (!rt[e[i].y]||geq(rt[e[i].y],Rt,0,N)){
rt[e[i].y]=Rt,pre[e[i].y]=x;
Push(make_pair(Rt,e[i].y));
}else for (;cnt>CNT;--cnt) w[cnt]=len[cnt]=ls[cnt]=rs[cnt]=0;
}
}
}
int main(){
n=iut(),m=iut(),two[0]=1;
if (n==1) return !printf("0\n1\n1");
for (int i=1;i<=N;++i) two[i]=2ll*two[i-1]%mod;
for (int i=1;i<=m;++i){
int x=iut(),y=iut(),w=iut();
e[++et]=(node){y,w,as[x]},as[x]=et;
e[++et]=(node){x,w,as[y]},as[y]=et;
}
S=iut(),T=iut(),Dijkstra(S);
if (pre[T]){
for (int _T=T;_T;_T=pre[_T]) st[++Top]=_T;
printf("%d\n%d\n",w[rt[T]],Top);
for (int i=Top;i;--i)
printf("%d%c",st[i],i==1?10:32);
}else printf("-1");
return 0;
}

#主席树,Dijkstra,哈希#CF464E The Classic Problem的更多相关文章

  1. 数据结构(主席树):HDU 4729 An Easy Problem for Elfness

    An Easy Problem for Elfness Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65535/65535 K (J ...

  2. LCA+主席树 (求树上路径点权第k大)

      SPOJ 10628. Count on a tree (树上第k大,LCA+主席树) 10628. Count on a tree Problem code: COT You are given ...

  3. 51Nod1863 Travel 主席树 最短路 Dijkstra 哈希

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1863.html 题目传送门 - 51Nod1863 题意 有 n 个城市,有 m 条双向路径连通它们 ...

  4. 【CF464E】The Classic Problem(主席树+最短路)

    点此看题面 大致题意: 给你一张无向图,每条边的边权为\(2^{x_i}\),求\(s\)到\(t\)的最短路. 最短路 最短路,首先考虑\(Dijkstra\).这里用\(SPFA\)似乎不太好,因 ...

  5. Codeforces 464E The Classic Problem(主席树+最短路+哈希,神仙题)

    题目链接 题意:给出一张 \(n\) 个点 \(m\) 条边的无向图,第 \(i\) 条边连接 \(u_i,v_i\),边权为 \(2^{w_i}\),求 \(s\) 到 \(t\) 的最短路. \( ...

  6. Codeforces 464E #265 (Div. 1) E. The Classic Problem 主席树+Hash

    E. The Classic Problem http://codeforces.com/problemset/problem/464/E 题意:给你一张无向带权图,求S-T的最短路,并输出路径.边权 ...

  7. BZOJ_3207_花神的嘲讽计划Ⅰ_哈希+主席树

    BZOJ_3207_花神的嘲讽计划Ⅰ_哈希+主席树 Description 背景 花神是神,一大癖好就是嘲讽大J,举例如下: “哎你傻不傻的![hqz:大笨J]” “这道题又被J屎过了!!” “J这程 ...

  8. CodeForces 464E The Classic Problem | 呆克斯歘 主席树维护高精度

    题意描述 有一个\(n\)点\(m\)边的无向图,第\(i\)条边的边权是\(2^{a_i}\).求点\(s\)到点\(t\)的最短路长度(对\(10^9 + 7\)取模). 题解 思路很简单--用主 ...

  9. Codeforces 464E The Classic Problem (最短路 + 主席树 + hash)

    题意及思路 这个题加深了我对主席树的理解,是个好题.每次更新某个点的距离时,是以之前对这个点的插入操作形成的线段树为基础,在O(logn)的时间中造出了一颗新的线段树,相比直接创建n颗线段树更省时间. ...

  10. bzoj 1901: Zju2112 Dynamic Rankings -- 主席树,树状数组,哈希

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MB Description 给定一个含有n个数的序列a[1] ...

随机推荐

  1. win32 - 使用Desktop Duplication API复制桌面图像

    该代码来源于codeproject,经过测试发现,在屏幕处于旋转的情况下捕获的图像是黑色的.暂时没有找到原因. 代码开箱即用, #define WIN32_LEAN_AND_MEAN #include ...

  2. Feign入门介绍

    Feign入门介绍 基本概述 除Feign之外,在Java中经常使用的HTTP客户端组件主要有3个,如下: (1)HttpURLConnection,JDK自带 (2)Apache HttpClien ...

  3. 使用Xilinx MIG验证硬件DDR设计

    1     导读 MIG 是xilinx的memory控制器,功能强大,接口易用.当硬件设计在设计对应的DDR接口时,最好先用MIG去配置一遍DDR的管脚约束.电平约束,从而避免硬件设计好了,实际却无 ...

  4. 【Azure 应用服务】Azure Function 部署槽交换时,一不小心把预生产槽上的配置参数交换到生产槽上,引发生产错误

    问题描述 部署Function代码先到预生产槽中,进行测试后通过交换方式,把预生产槽中的代码交换到生产槽上,因为在预生产槽中的设置参数值与生产槽有不同,但是在交换的时候,没有仔细检查.导致在交换的时候 ...

  5. 【Azure 应用服务】在安全漏洞扫描中发现有泄露服务器IIS版本的情况,如何实现屏蔽服务版本号信息呢?

    问题描述 当对Azure App Service应用进行安全扫描时,发现了HTTP/S请求的响应头中会包含服务端IIS的版本信息,这是一个低风险因素. 如: Server: Microsoft-IIS ...

  6. 浅入Kubernetes(13):dashboard、api、访问配置

    目录 Kubectl 命令大全 安装 Kubernetes-Dashboard RESTful API 鉴权 注解 Pod YAML 结构 配置 Kubectl 命令大全 在前面,我们学习到了一些 K ...

  7. 一文带你了解 「图数据库」Nebula 的存储设计和思考

    本文首发于 Nebula Graph Community 公众号 在上次的 nebula-storage on nLive 直播中,来自 Nebula 存储团队的负责人王玉珏(四王)同大家分享了 ne ...

  8. Advanced .Net Debugging 3:基本调试任务(上)

    一.简介 这是我的<Advanced .Net Debugging>这个系列的第三篇文章.这个系列的每篇文章写的周期都要很长,因为每篇文章都是原书的一章内容(太长的就会分开写).再者说,原 ...

  9. GDB调试入门笔记

    目录 What? Why How 安装GDB 安装命令 查看是否安装成功 调试简单的程序 预备一个程序 调试 使用 break info list next print step 一些小技巧 在gdb ...

  10. Edge 语音识别 生成文字 显示在input new webkitSpeechRecognition()

    Edge 语音识别 生成文字 显示在input new webkitSpeechRecognition() 代码 <html> <head> <style> bod ...