CF 787D Legacy(线段树思想构图+最短路)
2 seconds
256 megabytes
standard input
standard output
Rick and his co-workers have made a new radioactive formula and a lot of bad guys are after them. So Rick wants to give his legacy to Morty before bad guys catch them.
There are n planets in their universe numbered from 1 to n. Rick is in planet number s (the earth) and he doesn't know where Morty is. As we all know, Rick owns a portal gun. With this gun he can open one-way portal from a planet he is in to any other planet (including that planet). But there are limits on this gun because he's still using its free trial.

By default he can not open any portal by this gun. There are q plans in the website that sells these guns. Every time you purchase a plan you can only use it once but you can purchase it again if you want to use it more.
Plans on the website have three types:
- With a plan of this type you can open a portal from planet v to planet u.
- With a plan of this type you can open a portal from planet v to any planet with index in range [l, r].
- With a plan of this type you can open a portal from any planet with index in range [l, r] to planet v.
Rick doesn't known where Morty is, but Unity is going to inform him and he wants to be prepared for when he finds and start his journey immediately. So for each planet (including earth itself) he wants to know the minimum amount of money he needs to get from earth to that planet.
The first line of input contains three integers n, q and s (1 ≤ n, q ≤ 105, 1 ≤ s ≤ n) — number of planets, number of plans and index of earth respectively.
The next q lines contain the plans. Each line starts with a number t, type of that plan (1 ≤ t ≤ 3). If t = 1 then it is followed by three integers v, u and w where w is the cost of that plan (1 ≤ v, u ≤ n, 1 ≤ w ≤ 109). Otherwise it is followed by four integers v, l, r and w where w is the cost of that plan (1 ≤ v ≤ n, 1 ≤ l ≤ r ≤ n, 1 ≤ w ≤ 109).
In the first and only line of output print n integers separated by spaces. i-th of them should be minimum money to get from earth to i-th planet, or - 1 if it's impossible to get to that planet.
3 5 1
2 3 2 3 17
2 3 2 2 16
2 2 2 3 3
3 3 1 1 12
1 3 3 17
0 28 12
4 3 1
3 4 1 3 12
2 2 3 4 10
1 2 4 16
0 -1 -1 12
In the first sample testcase, Rick can purchase 4th plan once and then 2nd plan in order to get to get to planet number 2.
题目链接:CF 787D
很脑洞的一道题,比较好的做法是用线段树分割区间的思想,把1-n看成区间构建两颗线段树A和B,然后把所有的子区间都看成一个点,这样后面的加边就是对这些区间加边了,构建好A和B,A父子节点之间自底向上加有向边,B树自顶向下加有向边,然后把B树的子节点加无向边到对应的A树的子节点,代表这些点可以推出(到达)哪些点,由于一开始在子节点s(A[s]还是B[s]无所谓,两者本来就是强连通的),哪里都不能去,因此最后要检查的就是B树的子节点的dis值(在A数的话哪里都可以)。
然后就是三种区间操作
1:u->v,加边$<A的叶子节点u,B的叶子节点v,w>$
2:u->[l,r],加边$<A的叶子节点u,\{B树中[l,r]区间对应的节点集合\},w>$
3:[l,r]->v,加边$<\{A树中[l,r]区间对应的节点集合\},B树的叶子节点v,w>$
这样一来三种边都不会多也不会少刚好可以到达正确的点。然后从B[s]的跑最短路即可,最后检查B[i]的dis即可,当然一开始要把A、B树的叶子节点记录下来方便后面加边使用
边数最坏情况应该是每一层左右均取两个区间,一直递归下去,有$log_{2}N$层,因此边数大约是$O(4*q*log_{2}N+2N)$
代码:
#include <stdio.h>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <string>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 1e5 + 7;
struct edge
{
int to, nxt;
LL w;
edge() {}
edge(int _to, int _nxt, LL _w): to(_to), nxt(_nxt), w(_w) {}
} E[N * 68];
int head[N << 2], tot;
LL d[N << 2];
bitset < N << 2 > vis;
int id[2][N << 2], sz;
vector<int>st;
int A[N], B[N]; void init()
{
CLR(head, -1);
tot = 0;
sz = 0;
}
inline void add(int s, int t, LL w)
{
E[tot] = edge(t, head[s], w);
head[s] = tot++;
}
void build(int k, int l, int r, int o)
{
id[o][k] = ++sz;
if (l == r)
{
if (o)
A[l] = id[o][k];
else
B[l] = id[o][k];
return ;
}
else
{
int mid = MID(l, r);
build(LC(k), l, mid, o);
build(RC(k), mid + 1, r, o);
if (o) //A树自底向上
{
add(id[o][LC(k)], id[o][k], 0);
add(id[o][RC(k)], id[o][k], 0);
}
else//B树自顶向下
{
add(id[o][k], id[o][LC(k)], 0);
add(id[o][k], id[o][RC(k)], 0);
}
}
}
void Findset(int k, int l, int r, int ql, int qr, int o)
{
if (ql <= l && r <= qr)
st.push_back(id[o][k]);
else
{
int mid = MID(l, r);
if (qr <= mid)
Findset(LC(k), l, mid, ql, qr, o);
else if (ql > mid)
Findset(RC(k), mid + 1, r, ql, qr, o);
else
Findset(LC(k), l, mid, ql, mid, o), Findset(RC(k), mid + 1, r, mid + 1, qr, o);
}
}
void SPFA(int s)
{
queue<int>Q;
Q.push(s);
vis.reset();
CLR(d, INF);
d[s] = 0;
while (!Q.empty())
{
int u = Q.front();
Q.pop();
vis[u] = 0;
for (int i = head[u]; ~i; i = E[i].nxt)
{
int v = E[i].to;
if (d[v] > d[u] + E[i].w)
{
d[v] = d[u] + E[i].w;
if (!vis[v])
{
vis[v] = 1;
Q.push(v);
}
}
}
}
}
int main(void)
{
int n, q, s, i, ops;
while (~scanf("%d%d%d", &n, &q, &s))
{
init();
build(1, 1, n, 1);
build(1, 1, n, 0);
for (i = 1; i <= n; ++i)
{
add(A[i], B[i], 0);
add(B[i], A[i], 0);
}
for (i = 0; i < q; ++i)
{
scanf("%d", &ops);
if (ops == 1)
{
int u, v;
LL w;
scanf("%d%d%I64d", &u, &v, &w);
add(A[u], B[v], w);
}
else if (ops == 2)
{
int u, l, r;
LL w;
scanf("%d%d%d%I64d", &u, &l, &r, &w);
st.clear();
Findset(1, 1, n, l, r, 0);
for (auto &x : st)
add(A[u], x, w);
}
else if (ops == 3)
{
int v, l, r;
LL w;
scanf("%d%d%d%I64d", &v, &l, &r, &w);
st.clear();
Findset(1, 1, n, l, r, 1);
for (auto &x : st)
add(x, B[v], w);
}
}
SPFA(B[s]);
for (i = 1; i <= n; ++i)
printf("%I64d%c", d[B[i]] == 0x3f3f3f3f3f3f3f3f ? -1 : d[B[i]], " \n"[i == n]);
}
return 0;
}
CF 787D Legacy(线段树思想构图+最短路)的更多相关文章
- Codeforces 787D. Legacy 线段树建模+最短路
D. Legacy time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...
- codeforces 787D - Legacy 线段树优化建图,最短路
题意: 有n个点,q个询问, 每次询问有一种操作. 操作1:u→[l,r](即u到l,l+1,l+2,...,r距离均为w)的距离为w: 操作2:[l,r]→u的距离为w 操作3:u到v的距离为w 最 ...
- Codeforces 787D Legacy 线段树 最短路
题意: 有\(n(1 \leq n \leq 10^5)\)个点,\(q(1 \leq q \leq 10^5)\)条路和起点\(s\) 路有三种类型: 从点\(v\)到点\(u\)需要花费\(w\) ...
- 【转】Codeforces Round #406 (Div. 1) B. Legacy 线段树建图&&最短路
B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...
- [CF787D]遗产(Legacy)-线段树-优化Dijkstra(内含数据生成器)
Problem 遗产 题目大意 给出一个带权有向图,有三种操作: 1.u->v添加一条权值为w的边 2.区间[l,r]->v添加权值为w的边 3.v->区间[l,r]添加权值为w的边 ...
- CF786B Legacy && 线段树优化连边
线段树优化连边 要求点 \(x\) 向区间 \([L, R]\) 连边, 一次的复杂度上限为 \(O(n)\) 然后弄成线段树的结构 先父子连边边权为 \(0\) 这样连边就只需要连父亲就可以等效于连 ...
- Codeforces Round #406 (Div. 1) B. Legacy 线段树建图跑最短路
B. Legacy 题目连接: http://codeforces.com/contest/786/problem/B Description Rick and his co-workers have ...
- Codeforces Round #406 (Div. 2) D. Legacy 线段树建模+最短路
D. Legacy time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...
- CodeForces - 786B Legacy (线段树+DIjkstra+思维)
题意:给N个点和Q条选项,有三种类型的选项:1.从u到v花费w修建一条路:2.从u到下标区间为[L,R]的点花费w修建一条路; 3.从下标区间为[L,R]的点到u花费w修建一条路. 然后求起点s到其余 ...
随机推荐
- esdoc 自动生成接口文档介绍
原文地址:https://www.xingkongbj.com/blog/esdoc/creat-esdoc.html 官网 ESDoc:https://esdoc.org/ JSDoc:http:/ ...
- (排班表三)导出列名不固定的Grid表格到Excel
将班表信息导出Excel表格保存到本地 要求:文档名称为[XXXX]年X月值班表 文档显示的效果: 实现代码: //导出Excel值班表 private void btn_export_1_Click ...
- Java - 基础数据类型的极值
- intellij idea 添加动态 user library(java.lang.VerifyError)【转】
使用IDEA的时候有时要用到eclipse的user library,由于两个IDE导入library的方式不同导致我们找不到导入user library的方法. 查IDEA的官方文档,找到方法如下: ...
- FreeBSD--如何最有效率的安装软件
Freebsd 下如何最有效率的安装软件 From <https://www.cnblogs.com/apexchu/p/4131821.html> FreeBSD的默认下载工具是fetc ...
- 【Effective C++读书笔记】序
C++ 是一个难学易用的语言! [C++为什么难学?] C++的难学,不仅在其广博的语法,以及语法背后的语义,以及语义背后的深层思维,以及深层思维背后的对象模型: C++的难学还在于它提供了四种不同而 ...
- 海康威视面试python后端题
1. 请简述三次握手和四次挥手: 答:首先TCP是传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接,在建立TCP连接时,需要客户端和服务器总共发送3个包. 三次握手的目的是连接服务器的指 ...
- opencv 图像的线性混合
1 线性混合理论 g(x) = (1-α)*f1(x) + α*f2(x) 其中,α代表图像的权重 #include<iostream> #include<opencv2/openc ...
- debug注意事项
1 先看关键代码是否正确,然后查一遍是否有变量名打错. 2 再看初始化有没有问题 3 再把范围开大和开int64(这应该刚开始看题就要注意,在不爆内存的情况下开int64) 4 静态调试,输出中间值. ...
- WPF里ItemsControl的分组实现
我们在用到ItemsControl时,有时会用到分组,如ListBox,ListView,DataGrid.WPF的ItemsControl可以实现分组,是依托于GroupStyle,以ListBox ...