CF 464E The Classic Problem
补一补之前听课时候的题。
考虑使用dij算法求最短路,因为边权存不下,所以考虑用主席树维护二进制位,因为每一次都只会在一个位置进行修改,所以可以暴力进位,这样均摊复杂度是对的。
《算法导论》给了证明:对于一个有$k$位的二进制计数器,假设每一次都从第0位$+1$,那么我们发现执行$n$次加法之后,发现第零位会变$\left \lfloor \frac{n}{1} \right \rfloor$次,第一位会变$\left \lfloor \frac{n}{2} \right \rfloor$次...而第$n$位会变$\left \lfloor \frac{n}{2^n} \right \rfloor$次,这样子所有的操作次数就相当于$\sum_{i = 0}^{k - 1}\left \lfloor \frac{i}{2^i} \right \rfloor < n * \sum_{i = 0}^{\infty}\frac{1}{2^i} = 2n$,所以最坏情况下的时间为$O(n)$,每一次操作的均摊时间复杂度为$O(n) / n = O(1)$。
这样子只需要借助主席树写一个时间为$O(log)$的$cmp$函数就可以用堆优化dijkskra了,遇到进位就在线段树上暴力搞一搞,反正复杂度是对的。
数太大了直接用题目中给的$seed = 2, Mod = 1e9 + 7$的哈希哈希一下就好了。
时间复杂度$O(nlog^2n)$。
感觉就像是对着大佬的题解抄了一遍。
Code:
#include <cstdio>
#include <cstring>
#include <queue>
#include <cstdlib>
using namespace std; const int N = 1e5 + ;
const int P = 1e9 + ; int n, m, st, ed, lim = , bin[N << ];
int tot = , head[N], pre[N]; struct Edge {
int to, nxt, val;
} e[N << ]; inline void add(int from, int to, int val) {
e[++tot].to = to;
e[tot].val = val;
e[tot].nxt = head[from];
head[from] = tot;
} inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > ''|| ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline void chkMax(int &x, int y) {
if(y > x) x = y;
} namespace PSegT {
struct SegNode {
int lc, rc, w;
} s[N * ]; int nodeCnt, root[N]; #define mid ((l + r) >> 1) bool cmp(int x, int l, int r, int y) {
if(l == r) return s[x].w > s[y].w;
if(s[s[x].rc].w == s[s[y].rc].w) return cmp(s[x].lc, l, mid, s[y].lc);
else return cmp(s[x].rc, mid + , r, s[y].rc);
} bool modify(int &x, int l, int r, int pos, int y) {
s[x = ++nodeCnt] = s[y];
if(l == r) {
s[x].w = s[y].w ^ ;
return s[y].w;
} int res;
if(pos > mid) res = modify(s[x].rc, mid + , r, pos, s[y].rc);
else {
res = modify(s[x].lc, l, mid, pos, s[y].lc);
if(res) res = modify(s[x].rc, mid + , r, mid + , s[y].rc);
} s[x].w = (1LL * s[s[x].rc].w * bin[mid - l + ] % P + s[s[x].lc].w) % P;
return res;
} } using namespace PSegT; struct Node {
int x, rt; bool operator < (const Node &oth) const {
return cmp(rt, , lim, oth.rt);
} };
priority_queue <Node> Q; void dfs(int x, int dep) {
if(x == st) {
printf("%d\n%d ", dep, x);
return;
} dfs(pre[x], dep + );
printf("%d ", x);
} inline void out() {
printf("%d\n", s[root[ed]].w);
dfs(ed, );
printf("\n");
exit();
} int main() {
read(n), read(m);
for(int x, y, v, i = ; i <= m; i++) {
read(x), read(y), read(v);
add(x, y, v), add(y, x, v);
chkMax(lim, v);
}
lim += ;
read(st), read(ed); for(int i = bin[] = ; i <= lim; i++)
bin[i] = 1LL * bin[i - ] * % P; nodeCnt = ;
Q.push((Node) {st, root[st]});
for(; !Q.empty(); ) {
Node now = Q.top(); Q.pop();
if(now.rt != root[now.x]) continue;
if(now.x == ed) out();
for(int i = head[now.x]; i; i = e[i].nxt) {
int y = e[i].to, v;
modify(v, , lim, e[i].val, root[now.x]);
if(!root[y] || cmp(root[y], , lim, v)) {
root[y] = v;
Q.push((Node) {y, root[y]});
pre[y] = now.x;
}
}
} puts("-1");
return ;
}
CF 464E The Classic Problem的更多相关文章
- [Codeforces 464E] The Classic Problem(可持久化线段树)
[Codeforces 464E] The Classic Problem(可持久化线段树) 题面 给出一个带权无向图,每条边的边权是\(2^{x_i}(x_i<10^5)\),求s到t的最短路 ...
- CodeForces 464E The Classic Problem | 呆克斯歘 主席树维护高精度
题意描述 有一个\(n\)点\(m\)边的无向图,第\(i\)条边的边权是\(2^{a_i}\).求点\(s\)到点\(t\)的最短路长度(对\(10^9 + 7\)取模). 题解 思路很简单--用主 ...
- Codeforces 464E. The Classic Problem
题目大意 给定一张$n$个点, $m$条边的无向图,求$S$ 到$T$的最短路,其中边权都是$2^k$的形式$n,m,k<=10^5$,结果对$10^9+7$取模 题解 大佬好厉害 跑一边dij ...
- Codeforces 464E The Classic Problem (最短路 + 主席树 + hash)
题意及思路 这个题加深了我对主席树的理解,是个好题.每次更新某个点的距离时,是以之前对这个点的插入操作形成的线段树为基础,在O(logn)的时间中造出了一颗新的线段树,相比直接创建n颗线段树更省时间. ...
- Codeforces 464E The Classic Problem(主席树+最短路+哈希,神仙题)
题目链接 题意:给出一张 \(n\) 个点 \(m\) 条边的无向图,第 \(i\) 条边连接 \(u_i,v_i\),边权为 \(2^{w_i}\),求 \(s\) 到 \(t\) 的最短路. \( ...
- Codeforces 464E #265 (Div. 1) E. The Classic Problem 主席树+Hash
E. The Classic Problem http://codeforces.com/problemset/problem/464/E 题意:给你一张无向带权图,求S-T的最短路,并输出路径.边权 ...
- 把一个序列转换成严格递增序列的最小花费 CF E - Sonya and Problem Wihtout a Legend
//把一个序列转换成严格递增序列的最小花费 CF E - Sonya and Problem Wihtout a Legend //dp[i][j]:把第i个数转成第j小的数,最小花费 //此题与po ...
- cf 633B A trivial problem
Mr. Santa asks all the great programmers of the world to solve a trivial problem. He gives them an i ...
- 【dp/贪心】CF 780 (Div. 3), problem: (C) Get an Even String
Problem - C - Codeforces 难度: 1300 input 6 aabbdabdccc zyx aaababbb aabbcc oaoaaaoo bmefbmuyw output ...
随机推荐
- nyoj-155-求高精度幂(java大数)
题目链接 import java.util.*; import java.math.*; public class Main{ public static void main(String[] arg ...
- Memcache mutex设计模式
Memcache mutex设计模式 转自:https://timyang.net/programming/memcache-mutex/ 场景 Mutex主要用于有大量并发访问并存在cache过期的 ...
- hdu 4632 回文子序列计数
水题 #include<iostream> #include<stdio.h> #include<cstring> #include<algorithm> ...
- UVA - 1471 Defense Lines (set/bit/lis)
紫薯例题+1. 题意:给你一个长度为n(n<=200000)的序列a[n],求删除一个连续子序列后的可能的最长连续上升子序列的长度. 首先对序列进行分段,每一段连续的子序列的元素递增,设L[i] ...
- 如何卸载Python通过setup.py安装的模块
0,pip uninstall xxxx 1.找到egg sudo easy_install -m BitVector .... Using /usr/local/lib/python2./ ...
- LeetCode Maximum Distance in Arrays
原题链接在这里:https://leetcode.com/problems/maximum-distance-in-arrays/description/ 题目: Given m arrays, an ...
- Unity物体上下反复漂浮效果
using UnityEngine;using System.Collections;// 主界面的开始按钮使用该脚本,控制上下来回浮动public class Floating : MonoBeha ...
- Directx 9 VS2015环境搭建
安装好Directx9 sdk和vs2015后 打开vs,新建项目 --> c++项目 -->win32控制台应用程序-->空项目 创建项目后,右键项目属性, 包含目录 D:\Pr ...
- JSP Servlet中的Request和Response的简单研究
本文参考了几篇文章所得,参考目录如下: 1.http://www.cnblogs.com/guangshan/p/4198418.html 2.http://www.iteye.com/problem ...
- django1.7+nginx1.4.4的static配置
静态文件指像css,js,images之类的文件. 1.工程配置setting.py STATIC_URL = /static/ STATIC_ROOT = /home/www/winingcpi/s ...