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到其余 ...
随机推荐
- Git工作流指南:功能分支工作流(转)
一旦你玩转了集中式工作流,在开发过程中可以很简单地加上功能分支,用来鼓励开发者之间协作和简化交流. 功能分支工作流背后的核心思路是所有的功能开发应该在一个专门的分支,而不是在master分支上.这个隔 ...
- react中内联样式的z-index不起作用.
<div style={{z-index: -100}} > hello,money. </div> 以上z-index样式如上写法是不起作用,原因是在react中内联样式的写 ...
- 本地预览的vue项目,在githubpage静态展示
本地项目github静态展示 前提 在本地npm run dev后能够在本地端口正常显示 githubpage为自己的静态页面 上线 config/index.js中设置assetsPublicPat ...
- OCCI线程安全
线程是任务调度的基本单位,一个进程中可以有多个线程,每个线程有自己的堆栈空间, 进程中的代码段.数据段和堆栈对进程中的线程是可见的.在使用线程时通常都要考虑数据的安全访问. 常用的线程同步方法有: 互 ...
- CMD批处理复制目录下所有文件
从我接触编程时,WIN7已经是最普及的系统了. 有一天,我需要在服务器更新某个软件或游戏的时候,我都需要先在其中一台服务器下载更新, 然后同步到其他服务器,而且这种操作也是非常频繁的,我就想写个批处理 ...
- Mybatis-传参
单参数传递 在mapper文件使用动态SQL时,传入参数的名称任意.不影响参数传入的结果 多参数传递 默认传递方式 自动将传入的参数进行排序,并用arg1…argeN或者param1…paramN赋值 ...
- table选项卡
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- PHP时间日期操作增减(date strtotime) 加一天 加一月
date_default_timezone_set('PRC'); //默认时区 //当前的时间增加5天 $date1 = "2014-11-11"; echo date('Y-m ...
- 笔记-scrapy-signal
笔记-scrapy-signal 1. scrapy singal 1.1. 信号机制 scrapy的信号机制主要由三个模块完成 signals.py 定义信号量 signalmana ...
- 如何在react里嵌入iframe?
无法访问iframe地址 index.js文件 import React from 'react'; import ReactDOM from 'react-dom'; import App from ...