B - Legacy

CodeForces - 787D

这个题目开始看过去还是很简单的,就是一个最短路,但是这个最短路的建图没有那么简单,因为直接的普通建图边太多了,肯定会超时的,所以要用线段树来优化建图。

这个题目我一开始也没想到,不知道怎么用线段树优化,然后看了一下题解,豁然开朗。

首先建两棵线段树,有点类似拆点,然后其中一颗从下往上建图A,一颗从上往下建图B。

从上往下建图的每一个叶子节点连着从上往下建图的每一个叶子节点。 权值都是0

p==1 那就直接是B 的叶子节点连着A 的叶子节点,权值为w

p==2 那就是A的叶子节点v 连着B的这个区间的节点

p==3 那就是A 的区间节点连着B的叶子节点v

起点在A这颗树的地球位置的根节点。

建完图之后就是跑一个最短路。

这个是大概思路,但是怎么写呢,

首先肯定是建树,建树的过程中建图,而且还要记录每一个节点的编号,并且记录每一个叶子节点的编号。

然后就是根据要求建图如果是区间就要进行查找这个区间节点就可以了。

接下来就是考验码力的时候了。

这个题目想清楚之后就不是很难写了,只是这个空间要注意,因为这个wa了三发。

这个方法要学习学习。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <vector>
#include <string>
#include <algorithm>
#include <iostream>
#include <map>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 2e5 + ;
int numa[maxn * ], numb[maxn * ], lefta[maxn * ], leftb[maxn * ];
ll d[maxn*], tot;
int n, m;
bool vis[maxn*];
struct edge {
int from, to, dist;
edge(int from=, int to=, int dist=) :from(from), to(to), dist(dist) {}
};
struct heapnode {
int u;
ll d;
heapnode(ll d=, int u=) : d(d), u(u) {}
bool operator<(const heapnode &a) const {
return a.d < d;
}
}; vector<edge> vec;
vector<int> g[maxn*]; void add(int u,int v,int w)
{
vec.push_back(edge(u, v, w));
int m = vec.size();
g[u].push_back(m - );
// printf("u=%d v=%d w=%d\n", u, v, w);
} void dijkstra(int s) {
priority_queue<heapnode>que;
for (int i = ; i <= tot; i++) d[i] = inf64;
d[s] = ;
memset(vis, , sizeof(vis));
que.push(heapnode(, s));
while (!que.empty()) {
heapnode x = que.top(); que.pop();
int u = x.u;
if (vis[u]) continue;
vis[u] = ;
for (int i = ; i < g[u].size(); i++) {
edge &e = vec[g[u][i]];
// printf("u=%d e.to=%d e.dist=%d\n", u, e.to, e.dist);
// printf("d[%d]=%lld d[%d]=%lld\n", u, d[u], e.to, d[e.to]);
if (d[e.to] > d[u] + e.dist) {
// printf("ww\n");
d[e.to] = d[u] + e.dist;
que.push(heapnode(d[e.to], e.to));
}
}
}
for(int i=;i<=n;i++)
{
if (d[lefta[i]] >= inf64) printf("-1 ");
else printf("%lld ", d[lefta[i]]);
}
} void builda(int id,int l,int r)
{
numa[id] = ++tot;
int mid = (l + r) >> ;
if(l==r)
{
lefta[l] = tot;
return;
}
builda(id << , l, mid);
builda(id << | , mid + , r);
add(numa[id << ], numa[id], );
add(numa[id << | ], numa[id], );
} void buildb(int id,int l,int r)
{
numb[id] = ++tot;
int mid = (l + r) >> ;
if(l==r)
{
leftb[l] = tot;
return;
}
buildb(id << , l, mid);
buildb(id << | , mid + , r);
add(numb[id], numb[id << ], );
add(numb[id], numb[id << | ], );
} void build3(int n)
{
for (int i = ; i <= n; i++) add(leftb[i], lefta[i], );
} void updatea(int id,int l,int r,int x,int y,int b,int w)
{
if (x <= l && y >= r) {
add(numa[id], b, w);
return;
}
int mid = (l + r) >> ;
if (x <= mid) updatea(id << , l, mid, x, y, b, w);
if (y > mid) updatea(id << | , mid + , r, x, y, b, w);
} void updateb(int id,int l,int r,int x,int y,int a,int w)
{
if(x<=l&&y>=r)
{
add(a, numb[id], w);
return;
}
int mid = (l + r) >> ;
if (x <= mid) updateb(id << , l, mid, x, y, a, w);
if (y > mid) updateb(id << | , mid + , r, x, y, a, w);
} int main()
{
int s;
tot = ;
scanf("%d%d%d", &n, &m, &s);
builda(, , n), buildb(, , n), build3(n);
while(m--)
{
int opt, u, v, l, r, w;
scanf("%d", &opt);
if (opt == ) {
scanf("%d%d%d", &u, &v, &w);
add(lefta[u], leftb[v], w);
}
if(opt==)
{
scanf("%d%d%d%d", &u, &l, &r, &w);
updateb(, , n, l, r, lefta[u], w);
}
if(opt==)
{
scanf("%d%d%d%d", &u, &l, &r, &w);
updatea(, , n, l, r, leftb[u], w);
}
}
dijkstra(lefta[s]);
return ;
}

线段树+最短路

B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路的更多相关文章

  1. G. 神圣的 F2 连接着我们 线段树优化建图+最短路

    这个题目和之前写的一个线段树优化建图是一样的. B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路 之前这个题目可以相当于一个模板,直接套用就可以了. 不 ...

  2. CF786B Legacy 线段树优化建图 + spfa

    CodeForces 786B Rick和他的同事们做出了一种新的带放射性的婴儿食品(???根据图片和原文的确如此...),与此同时很多坏人正追赶着他们.因此Rick想在坏人们捉到他之前把他的遗产留给 ...

  3. [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路)

    [Codeforces 1197E]Culture Code(线段树优化建图+DAG上最短路) 题面 有n个空心物品,每个物品有外部体积\(out_i\)和内部体积\(in_i\),如果\(in_i& ...

  4. BZOJ5017 [SNOI2017]炸弹 - 线段树优化建图+Tarjan

    Solution 一个点向一个区间内的所有点连边, 可以用线段树优化建图来优化 : 前置技能传送门 然后就得到一个有向图, 一个联通块内的炸弹可以互相引爆, 所以进行缩点变成$DAG$ 然后拓扑排序. ...

  5. 【BZOJ3681】Arietta 树链剖分+可持久化线段树优化建图+网络流

    [BZOJ3681]Arietta Description Arietta 的命运与她的妹妹不同,在她的妹妹已经走进学院的时候,她仍然留在山村中.但是她从未停止过和恋人 Velding 的书信往来.一 ...

  6. 【ARC069F】Flags 2-sat+线段树优化建图+二分

    Description ​ 数轴上有 n 个旗子,第 ii 个可以插在坐标 xi或者 yi,最大化两两旗子之间的最小距离. Input ​ 第一行一个整数 N. ​ 接下来 N 行每行两个整数 xi, ...

  7. 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序

    题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足:  Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆.  现在 ...

  8. 【bzoj4699】树上的最短路(树剖+线段树优化建图)

    题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...

  9. 【BZOJ4276】[ONTAK2015]Bajtman i Okrągły Robin 线段树优化建图+费用流

    [BZOJ4276][ONTAK2015]Bajtman i Okrągły Robin Description 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2 ...

随机推荐

  1. Linq中带有迭代索引的Select扩展方法,为啥知道的人不多呢?

    一:背景 昨天在看C#函数式编程这本书的时候,有一处让我干着急,需求是这样: 给多行文字加上数字列表项. 针对这个需求你会如何快捷高效的给每个项目加上数字编号呢? 我看书中是这样实现的,如下代码 pu ...

  2. linux中操作k8s的基本命令-更新中

    linux中操作k8s的基本命令 最近工作中使用到了k8s,那么就来总结下平时使用到的基本的命令 获取某个namespace下的pod 获取某个namespace下的pod,展示出ip和pod信息 查 ...

  3. 常用Linux命令的基本使用

    01.常用Linux命令的基本使用 序号 命令 对应英文 作用 01 ls list 查看当前文件夹下的内容 02 pwd print work directory 查看当前所在文件夹 03 cd [ ...

  4. 爬虫的新手使用教程(python代理IP)

    前言 Python爬虫要经历爬虫.爬虫被限制.爬虫反限制的过程.当然后续还要网页爬虫限制优化,爬虫再反限制的一系列道高一尺魔高一丈的过程.爬虫的初级阶段,添加headers和ip代理可以解决很多问题. ...

  5. windows/linux下如何更换Python的pip源

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:xlixiaohui PS:如有需要Python学习资料的小伙伴可以 ...

  6. U - Obtain a Permutation CodeForces - 1294E 思维

    题解: 注意每一列与每一列之间互不影响,所以贪心地求出没一列的最小操作值,然后累加起来. 怎么求没一列的最小值呢?维护一个数组same表示其中same[i]=j表示将该序列向上翻滚i次有j个元素归位, ...

  7. Spring Cloud 系列之 Gateway 服务网关(三)

    本篇文章为系列文章,未读第一集的同学请猛戳这里: Spring Cloud 系列之 Gateway 服务网关(一) Spring Cloud 系列之 Gateway 服务网关(二) 本篇文章讲解 Ga ...

  8. Ubuntu上mysql, 通过python连接报错Can't connect to MySQL server on xxx (10061)

    通过sqlyog连接ubuntu上的mysql报错 试了试python直接连接也报同样的错 那应该就是ubuntu上mysql服务自己的问题了 查看mysql 版本 mysql -V root@clo ...

  9. [JS] 自己弄得个倒计时

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. MVC-过滤器-异常处理

    通常异常处理是用try{ }catch{ },导致代码重复冗余. 利用特性处理demo 若action中已经包含try catch 则是被异常处理过,则不会被上面异常捕获到. 不管是视图,还是调用的d ...