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 ...
随机推荐
- 常用服务搭建(nfs/ftp/samba)
一. NFS1. NFS简介NFS全称是network file systemNFS允许一个系统在网络上与他人共享目录和文件.通过使用NFS,用户和程序可以像访问本地文件一样访问远端系统上的文件. 假 ...
- C# 如何将对象写入文件
http://wenku.baidu.com/link?url=QwDRlO1TeoubnmtUOitXXTRa-eZ6QFKvEuyXyzLXD9c0qCRUV5TL9Fq7_HqvxrMcwsAL ...
- C#进阶之路(五):Linq初识
关于LINQ的文章,网上有很多,所以这篇文章我主要是总结下我自己的学习心得. 首先需要先了解的相关技术 1.隐式类型.匿名类型.对象初始化器 1)隐式类型,使用var关键字创建,C#编译器会根据用于初 ...
- JSONP原理及实现跨域方式
今天做页面时,后台给了个接口:https://a.a.com/a/a.json,我页面的上线地址是:http://b.b.com.显而易见,因为浏览器同源策略的限制,通过ajax无法无法取得json的 ...
- C#检查网络是否可以连接互联网
添加引用: using System.Runtime.InteropServices; using System.Net.NetworkInformation; [DllImport("wi ...
- 洛谷 3803 【模板】多项式乘法(FFT)
题目:https://www.luogu.org/problemnew/show/P3803 第一道FFT! https://www.cnblogs.com/zwfymqz/p/8244902.htm ...
- BZOJ3141:[HNOI2013]旅行
浅谈队列:https://www.cnblogs.com/AKMer/p/10314965.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem.p ...
- git ssh登录
.ssh下创建config文件 其内容: Host ipIdentityFile ~/.ssh/私钥文件名Port 22User git服务器的账号,不是git账号名(私钥文件名才是git账号名) 注 ...
- 【转】IMSI和IMEI
国际移动客户识别码(International Mobile Subscriber Identification Number) 为了在无线路径和整个GSM移动通信网上正确地识别某个移动客户,就必须给 ...
- Codeforces Problem - 38E - Let's Go Rolling!(DP)
E. Let's Go Rolling! time limit per test 2 seconds memory limit per test 256 megabytes input standar ...