题目大意

给定一张$n$个点, $m$条边的无向图,求$S$ 到$T$的最短路,其中边权都是$2^k$的形式$n,m,k<=10^5$,结果对$10^9+7$取模

题解

大佬好厉害

跑一边dijstra大家应该都想的到

但问题是维护最短路的距离怎么实现

我太菜了除了python啥都想不到

我们可以把距离拆成每一位,因为每一次只会加上一个数,直接开主席树维护就好了

时间复杂度什么的……感性理解一下就好了

比较大小直接二分哈希

 //minamoto
#include<bits/stdc++.h>
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,:;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=1e5+,mod=1e9+;
int n,m,head[N],Next[N<<],ver[N<<],edge[N<<];
int S,T,lim,b[N<<],rt[N],Pre[N],tot,cnt;
int L[N*],R[N*],sum[N*];
inline void add(int u,int v,int e){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
ver[++tot]=u,Next[tot]=head[v],head[v]=tot,edge[tot]=e;
}
bool cmp(int u,int v,int l,int r){
if(l==r) return sum[u]>sum[v];
int mid=(l+r)>>;
if(sum[R[u]]==sum[R[v]]) return cmp(L[u],L[v],l,mid);
else return cmp(R[u],R[v],mid+,r);
}
int update(int last,int &now,int l,int r,int k){
L[now=++cnt]=L[last],R[now]=R[last];
if(l==r){
sum[now]=sum[last]^;
return sum[last];
//每一个节点存的只有一位,如果加之前是1就要进位
}
int mid=(l+r)>>,res;
if(k>mid) res=update(R[last],R[now],mid+,r,k);
else{
res=update(L[last],L[now],l,mid,k);
if(res) res=update(R[last],R[now],mid+,r,k);
}
sum[now]=(1ll*sum[R[now]]*b[mid-l+]+sum[L[now]])%mod;
return res;
}
struct node{
int x,rt;
bool operator <(const node &b)const
{return cmp(rt,b.rt,,lim);}
};
priority_queue<node> q;
void dfs(int u,int dep){
if(u==S){printf("%d\n%d ",dep,u);return;}
dfs(Pre[u],dep+);
printf("%d ",u);
}
void print(int u){
printf("%d\n",sum[rt[u]]);
dfs(u,);exit();
}
int main(){
//freopen("testdata.in","r",stdin);
n=read(),m=read();
for(int i=;i<=m;++i){
int u,v,e;
u=read(),v=read(),e=read();
add(u,v,e);
cmax(lim,e);
}
lim+=;
b[]=;for(int i=;i<=lim;++i) b[i]=(1ll*b[i-]<<)%mod;
S=read(),T=read();
q.push((node){S,rt[S]});
while(!q.empty()){
node u=q.top();q.pop();
if(u.rt!=rt[u.x]) continue;
//如果不一样,说明已经在主席树上被修改了
//就给普通的判dijkstra一样就好了
if(u.x==T) print(T);
for(int i=head[u.x];i;i=Next[i]){
int v=ver[i],RT;
update(u.rt,RT,,lim,edge[i]);
if(!rt[v]||cmp(rt[v],RT,,lim))
rt[v]=RT,q.push((node){v,rt[v]}),Pre[v]=u.x;
}
}
puts("-1");
return ;
}

Codeforces 464E. The Classic Problem的更多相关文章

  1. [Codeforces 464E] The Classic Problem(可持久化线段树)

    [Codeforces 464E] The Classic Problem(可持久化线段树) 题面 给出一个带权无向图,每条边的边权是\(2^{x_i}(x_i<10^5)\),求s到t的最短路 ...

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

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

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

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

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

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

  5. CF 464E The Classic Problem

    补一补之前听课时候的题. 考虑使用dij算法求最短路,因为边权存不下,所以考虑用主席树维护二进制位,因为每一次都只会在一个位置进行修改,所以可以暴力进位,这样均摊复杂度是对的. <算法导论> ...

  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. [codeforces 528]B. Clique Problem

    [codeforces 528]B. Clique Problem 试题描述 The clique problem is one of the most well-known NP-complete ...

  8. codeforces.com/contest/325/problem/B

    http://codeforces.com/contest/325/problem/B B. Stadium and Games time limit per test 1 second memory ...

  9. Codeforces 442B Andrey and Problem(贪婪)

    题目链接:Codeforces 442B Andrey and Problem 题目大意:Andrey有一个问题,想要朋友们为自己出一道题,如今他有n个朋友.每一个朋友想出题目的概率为pi,可是他能够 ...

随机推荐

  1. 转 Android:文件下载和写入SD卡学习小结

    转自 http://blog.csdn.net/zzp_403184692/article/details/8160739  一.文件下载  Android开发中,有时需要从网上下载一些资源以供用户使 ...

  2. percona xtradb cluster test

    docker run --rm -ti -e CLUSTER_NAME=test -e MYSQL_ALLOW_EMPTY_PASSWORD=1 --entrypoint="bash&quo ...

  3. Gym101128G:Game of Cards

    题意: 有P摞纸牌和一个数字k,每次可以从一摞中拿0-k张牌,拿完再剩下的牌中的第一张数字是几,就必须再拿几张,谁不能拿谁输. emmm感觉好像就是裸的SG游戏啊,数据不大,递推出每一摞牌的SG值,然 ...

  4. (转)Docker镜像中的base镜像理解

    base 镜像有两层含义: 不依赖其他镜像,从 scratch 构建. 其他镜像可以之为基础进行扩展. 所以,能称作 base 镜像的通常都是各种 Linux 发行版的 Docker 镜像,比如 Ub ...

  5. javascript中的replace()方法

    javascript中有很多很好用的操作字符串和数组的方法,replace()就是其中一个. 看看基本用法 var str = '1234512345'; var newStr = str.repla ...

  6. https://itunes.apple.com/cn/app/apache-overkill/id410553807?mt=8uo%3D6

    https://itunes.apple.com/cn/app/apache-overkill/id410553807?mt=8uo%3D6 http://eplusgames.net/games/s ...

  7. Sql的行列转换

    创建表scores 一.传统的行列转换 纵表转横表 我们要转成的横表是这样子的: pivot是sql server 2005 提供的运算符,所以只要数据库在05版本以上的都可以使用.主要用于行和列的转 ...

  8. JS作用域理解(声明提升)

    1.JS解析步骤: a.预解析 将变量声明提升: 将函数声明及函数内容提升,可以理解成原来位置的函数在解析代码时已经提到代码初始位置: 块内的变量声明和函数声明也会被提升,例如if语句 遇到重名,只留 ...

  9. Perl 学习笔记-正则表达式应用篇

    1.以 m// 进行匹配 如:  m/roger/ ,  /roger/ 是它的简写;  在说明  qw// 时可以选择使用任何成对的定界符, 对应m//匹配也可以, 如写成:  m(roger)   ...

  10. C#通过Redis实现分布式锁

    Redis有三个最基本属性来保证分布式锁的有效实现: 安全性: 互斥,在任何时候,只有一个客户端能持有锁. 活跃性A:没有死锁,即使客户端在持有锁的时候崩溃,最后也会有其他客户端能获得锁,超时机制. ...