Codeforces 786B Legacy(线段树优化建图)
题目链接 Legacy
首先对于输入的$n$,建立一棵线段树。
显然线段树有大概$2n$个结点,每个节点对应一段区间
我们把这$2n$个结点加入我们的无向图中,一起跑最短路。
具体连边方案:
我们把这棵线段树复制一下,另外一棵倒过来。
首先第一棵线段树,每个结点向他的两个儿子连有向边,连到叶子结点的时候
叶子结点向原来的$n$个点连边
也就是说$[l, l]$向原来编号为$l$的这个点连边。
然后$1$到$n$这$n$个点分别向第二棵线段树的叶子结点分别连有向边
具体一点,$l$号点向$[l', l']$连边。
然后在第二棵线段树中,两个儿子向父亲连边,依次类推。
接着就是对给定的输入进行连边操作了。
对于点连向点的,普通操作就行了。
对于点连向区间的,把点连向第一棵线段树的结点。大概要连$logn$条边
对于区间连向点的,把第二棵线段树的结点连向这个点。大概也连$logn$条边
然后跑一边堆优化Dij就可以了。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define ls (i << 1)
#define rs (i << 1 | 1)
#define mid ((L + R) >> 1)
#define lson ls, L, mid
#define rson rs, mid + 1, R typedef long long LL;
typedef pair <int, int> PII; const int N = 2e6 + 10; struct node{
int u;
LL w;
friend bool operator < (const node &a, const node &b){
return a.w > b.w;
}
}; map <PII, int> mp;
int tot = 0;
int n, q, s, cnt;
LL dis[N];
vector <node> v[N]; void addedge(int x, int y, LL z){
v[x].push_back({y, z});
} void build(int i, int L, int R){
cnt = max(cnt, i);
if (L == R){
addedge(i + n, L, 0);
return;
} build(lson);
build(rson);
addedge(i + n, ls + n, 0);
addedge(i + n, rs + n, 0);
} void build2(int i, int L, int R){
if (L == R){
addedge(L, i + n + cnt, 0);
return;
} build2(lson);
build2(rson);
addedge(ls + n + cnt, i + n + cnt, 0);
addedge(rs + n + cnt, i + n + cnt, 0);
} void work1(int i, int L, int R, int l, int r, int u, LL val){
if (l <= L && R <= r){
addedge(u, i + n, val);
return;
} if (l <= mid) work1(lson, l, r, u, val);
if (r > mid) work1(rson, l, r, u, val);
} void work2(int i, int L, int R, int l, int r, int u, LL val){
if (l <= L && R <= r){
addedge(i + n + cnt, u, val);
return;
} if (l <= mid) work2(lson, l, r, u, val);
if (r > mid) work2(rson, l, r, u, val);
} void dij(int s, LL dis[], vector <node> v[]){
priority_queue <node> q;
static bool vis[N];
rep(i, 1, 2e6) dis[i] = 1e18, vis[i] = false;
q.push({s, 0});
dis[s] = 0;
while (!q.empty()){
int u = q.top().u; q.pop();
if (vis[u]) continue;
vis[u] = 1;
for (auto edge : v[u]) if (dis[u] + edge.w < dis[edge.u]){
dis[edge.u] = dis[u] + edge.w;
q.push({edge.u, dis[edge.u]});
}
}
} int main(){ scanf("%d%d%d", &n, &q, &s);
tot = n;
build(1, 1, n);
build2(1, 1, n); while (q--){
int op;
scanf("%d", &op);
if (op == 1){
int x, y;
LL z;
scanf("%d%d%lld", &x, &y, &z);
if (x == y) continue;
addedge(x, y, z);
}
else if (op == 2){
int u, l, r;
LL z;
scanf("%d%d%d%lld", &u, &l, &r, &z);
work1(1, 1, n, l, r, u, z);
} else{
int u, l, r;
LL z;
scanf("%d%d%d%lld", &u, &l, &r, &z);
work2(1, 1, n, l, r, u, z);
}
} dij(s, dis, v);
rep(i, 1, n) printf("%lld\n", (dis[i] < 1e18 ? dis[i] : -1));
return 0;
}
Codeforces 786B Legacy(线段树优化建图)的更多相关文章
- Codeforces.786B.Legacy(线段树优化建图 最短路Dijkstra)
题目链接 \(Description\) 有\(n\)个点.你有\(Q\)种项目可以选择(边都是有向边,每次给定\(t,u,v/lr,w\)): t==1,建一条\(u\to v\)的边,花费\(w\ ...
- CF786B Legacy 线段树优化建图 + spfa
CodeForces 786B Rick和他的同事们做出了一种新的带放射性的婴儿食品(???根据图片和原文的确如此...),与此同时很多坏人正追赶着他们.因此Rick想在坏人们捉到他之前把他的遗产留给 ...
- [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)
[Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...
- G. 神圣的 F2 连接着我们 线段树优化建图+最短路
这个题目和之前写的一个线段树优化建图是一样的. B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路 之前这个题目可以相当于一个模板,直接套用就可以了. 不 ...
- 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 最 ...
- BZOJ5017 [SNOI2017]炸弹 - 线段树优化建图+Tarjan
Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...
- 【BZOJ3681】Arietta 树链剖分+可持久化线段树优化建图+网络流
[BZOJ3681]Arietta Description Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中.但是她从未停止过和恋人 Velding 的书信往来.一 ...
- 【ARC069F】Flags 2-sat+线段树优化建图+二分
Description 数轴上有 n 个旗子,第 ii 个可以插在坐标 xi或者 yi,最大化两两旗子之间的最小距离. Input 第一行一个整数 N. 接下来 N 行每行两个整数 xi, ...
- 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序
题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足: Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆. 现在 ...
- 【bzoj4699】树上的最短路(树剖+线段树优化建图)
题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...
随机推荐
- 封装一个优雅的element ui表格组件
现在做后台系统用vue + elementUI 的越来越多,那element ui的 el-table 组件肯定也离不开.虽然element ui的table组件很好.但是表格和分页是分离的.每次写表 ...
- 【android】安卓的权限提示及版本相关
Only dangerous permissions require user agreement. The way Android asks the user to grant dangerous ...
- python-面试常用 --变量、内存管理(小整数池,引用计数)
执行Python程序的两种方法 第一种:交互式(jupyter就是对这种进行了封装) 优点:直接给出结果 缺点:无法保存 第二种:命令行式,通过Python解释器输入文本(pycharm对这种进行了封 ...
- VSCode编译C/C++(一)MinGW安装配置指南
为什么不用IDE? 更加专业.轻便.其过程对于理解计算机也有更多的帮助 安装过程: 首先进入http://mingw.org/ ,点击右侧最新发布,可以下载,然后安装 点击桌面MinGWInstal ...
- Selenium WebDriver- 操作浏览器的cookie
#encoding=utf-8 import unittest import time from selenium import webdriver from selenium.webdriver i ...
- python - 路径处理 和 模块导入
# -*- coding:utf-8 -*- '''@project: jiaxy@author: Jimmy@file: study_模块导入.py@ide: PyCharm Community E ...
- Spring 依赖注入(一、注入方式)
首先装配一个实体类People package com.maya.model; public class People { private int id; private String name; p ...
- map/set/object/array对比
map () { //数据结构横向对比, 增,查,改,删 let map = new Map() let array = [] //增 map.set('t',1) array.push({t:1}) ...
- 【bzoj1002】[FJOI2007]轮状病毒 矩阵树定理+高精度
题目描述 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图所示 N轮状病 ...
- 【Luogu】P2447外星千足虫(高斯消元)
题目链接 高斯消元解%2意义下的方程,Bitset优化一下. 在消的过程中就能顺便把有解的第一问求出来,记录一下访问过的最大行. #include<cstdio> #include< ...