整理的算法模板合集: ACM模板


目录

  • 线段树优化建边

题目传送门

由于本题的数据达到了1e5,所以如果直接全部暴力连边的话会达到O(n2)O(n^2)O(n2),时间包括内存都受不了。因此我们需要使用下面的线段树优化建边。

线段树优化建边

给你一个点 X ,让你和一个点集里的每一个点都连一条边。看上去我们只能一个一个连。

如果这个点集是连续的呢?我们就可以用线段树来优化建边了。

我们知道线段树的结构:


我们知道线段树的点是能够代表一段区间的

我们需要对于线段树的每个父亲与他的儿子建一条单向边

这有什么用呢?因为我们所要求的点集是一段连续的区间,而线段树的结点可以表示某一段区间,我们可以在线段树上找到对应的区间,然后向线段树上的点建边,就可以加快建边速度了。

例如我们要向[1,8][1,8][1,8] 里的所有点建边,我们只需要将 X 和线段树上 [1,8][1,8][1,8] 那个点连一条单向边就可以了。

[2,6][2,6][2,6] 的例子


我们在线段树上的边边权一般都是 0 ,边权直接赋给 X 连到线段树上的那条边即可

建树和寻找的代码和普通线段树差不多。需要注意的是线段树上结点的编号不要和已有的点重复,最后的结点直接连上该点就好。

上述内容链接:https://www.luogu.com.cn/blog/chengni5673/tu-lun-di-xiao-ji-qiao-yi-ji-kuo-zhan

这道题还涉及到了区间向某一个点连边的情况,我们再建一个棵线段树在树上反向建边就可以了。

代码:

注:如果使用结构体形式的线段树会T…

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#define x first
#define y second
#define int long long
#pragma GCC optimize("Ofast")
#define debug(x) cout << x << "ok" << endl
using namespace std;
typedef long long ll;
//typedef __int128 int;oj上可用,编译器上不可用
const ll N = 200007, M = N * 20, INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-8;
typedef pair<int, int >PII;int n_cnt, m, q, s, cnt;
int head[N << 2], ver[M], nex[M], tot;
ll edge[M];
bool vis[N << 2];
ll dist[N << 2];
int root, rootx, x, lx, rx;
int ls[N << 2], rs[N << 2];void init()
{memset(head, -1, sizeof head);tot = 1;
}void add(int x, int y, ll z)
{ver[tot] = y;edge[tot] = z;nex[tot] = head[x];head[x] = tot ++ ;
}inline int build_down(int l, int r)
{if(l == r){return l;}int mid = l + r >> 1;int p = ++ n_cnt;//要用新点,不然会重复ls[p] = build_down(l, mid);rs[p] = build_down(mid + 1, r);add(p, ls[p], 0);add(p, rs[p], 0);return p;
}inline int build_up(int l, int r)
{if(l == r){return l;}int mid = l + r >> 1;int p = ++ n_cnt;//要用新点,不然会重复ls[p] = build_up(l, mid);rs[p] = build_up(mid + 1, r);add(ls[p], p, 0);add(rs[p], p, 0);return p;
}inline void link(int l, int r, int x, ll dist, int p, int type)
{if(lx <= l && rx >= r){type ? add(p, x, dist) : add(x, p, dist);return ;}int mid = l + r >> 1;if(lx <= mid)link(l, mid, x, dist, ls[p], type);if(rx > mid)link(mid + 1, r, x, dist, rs[p], type);
}void dijkstra()
{memset(dist, 0x3f, sizeof dist);priority_queue<PII, vector<PII>, greater<PII> >q;dist[s] = 0;q.push({0, s});while(q.size()){int x = q.top().second;q.pop();if(vis[x])continue;vis[x] = 1;for(int i = head[x]; ~i;i = nex[i]){int y = ver[i];ll z = edge[i];if(dist[y] > dist[x] + z){dist[y] = dist[x] + z;q.push({dist[y], y});}}}
}signed main()
{init();scanf("%lld%lld%lld", &n_cnt, &q, &s);cnt = n_cnt;root = n_cnt + 1;//两个不同的根//debug(n_cnt);build_down(1, cnt);//正的线段树//debug(n_cnt);rootx = n_cnt + 1;//两个不同的根(n_cnt会变)build_up(1, cnt);//反图的线段树//debug(n_cnt);for(int i = 1; i <= q; ++ i){int op;scanf("%lld", &op);if(op == 1){int x, y, z;scanf("%lld%lld%lld", &x, &y, &z);add(x, y, z);continue;}ll distance;scanf("%lld%lld%lld%lld", &x, &lx, &rx, &distance);//实际上图中的点只有1~cnt个link(1, cnt, x, distance, op ^ 3 ? root : rootx, op - 2);}dijkstra();for(int i = 1; i <= cnt; ++ i){printf("%lld ", dist[i] == INF ? -1 : dist[i]);}return 0;
}

CF786B Legacy(线段树优化建边模板 + 最短路)相关推荐

  1. Codeforces 786B Legacy (线段树优化建图)

    Codeforces 786B Legacy (线段树优化建图) 题意:\(n\)个点,有\(3\)种连边操作:1.将\(u\)指向\(v\):2.将\(v\)指向编号在区间\([l,r]\)的点:3 ...

  2. CodeForces - 787D - Legacy(线段树优化建图+最短路)

    题目链接:点击查看 题目大意:给出 nnn 个点和 mmm 条边,现在需要求从 ststst 开始到所有点的最短路是多少,mmm 条边的给出方式如下: 1uvw1 \ u \ v \ w1 u v w ...

  3. Gym - 102174G 神圣的 F2 连接着我们 (线段树优化建图 + 多源最短路)

    Description 小白非常喜欢玩 "县际争霸" 这款游戏,虽然他的技术并不容乐观."县际争霸" 的地图共有两个县,每个县里各有 n n n 个据点.同一个 ...

  4. 线段树优化建图详解——区间连边之技巧,吊打紫题之利器

    我们从一道例题开始. CF786B Description Solution 朴素解法: 暴力连边+最短路 对于每次连边操作,我们逐一连边,最后在图上跑一遍单源最短路径算法即可. 时间复杂度 O ( ...

  5. UOJ#77. A+B Problem [可持久化线段树优化建边 最小割]

    UOJ#77. A+B Problem 题意:自己看 接触过线段树优化建图后思路不难想,细节要处理好 乱建图无果后想到最小割 白色和黑色只能选一个,割掉一个就行了 之前选白色必须额外割掉一个p[i], ...

  6. 【CF1045A】A Last chance【贪心】【线段树优化建图】【网络流构造方案】

    题意:有nnn个武器和mmm个飞船,武器有下面三种 从给定的集合SSS中击破一个. 在给定的区间[L,R][L,R][L,R]中击破一个. 对于给定的a,b,ca,b,ca,b,c,选择000个或22 ...

  7. Codeforces 1045. A. Last chance(网络流 + 线段树优化建边)

    题意 给你 \(n\) 个武器,\(m\) 个敌人,问你最多消灭多少个敌人,并输出方案. 总共有三种武器. SQL 火箭 - 能消灭给你集合中的一个敌人 \(\sum |S| \le 100000\) ...

  8. 洛谷P3588 [POI2015]PUS(线段树优化建图)

    题面 传送门 题解 先考虑暴力怎么做,我们把所有\(r-l+1-k\)中的点向\(x\)连有向边,表示\(x\)必须比它们大,那么如果这张图有环显然就无解了,否则的话我们跑一个多源最短路,每个点的\( ...

  9. CF786B Legacy 线段树优化建图

    洛谷题目链接 题意 首先想到单源最短路,但是如果暴力模拟就会导致从区间里每一个点连向另一个点时最坏情况时间复杂度达到O(N*N),显然会TLE.那么看到区间操作,自然会想到处理区间操作的数据结构,这一 ...

最新文章

  1. 智慧停车产业链市场全透析
  2. centos7 没有pip命令_Linux(CentOS7)部署系列---Docker编排应用部署方案
  3. mysql souece 慢_Mysql InnoDB在linux下用source命令执行sql脚本速度慢的问题解决
  4. science量子计算机,第一快讯|《Science》量子计算机被证明超越了经典计算机
  5. Moonlight 2紧随Silverlight而来
  6. 支付宝上线长辈模式: 字体图标加大 去除了营销推送
  7. SSAS - 1.学习记录
  8. MySQL索引. ref_mysql中索引利用情况(explain用法)
  9. 归并排序的时间复杂度
  10. 简单的爬虫爬取教务网获取成绩
  11. python学习笔记十——异常处理
  12. 洛谷 P3951 小凯的疑惑
  13. Filezilla server 使用教程
  14. linux怎么用jconsole_怎么在linux jconsole
  15. 迅为4412开发平台Zigbee模块在物联网智能家居中的应用
  16. mysql错误:Table XXX is marked as crashed and should be repaire
  17. 网页形式的php抓取文件,PHP 抓取网页源文件
  18. 保存360锁屏壁纸批量修改文件后缀名
  19. 幸运大转盘抽奖(前端)
  20. 趣图:程序员睡不着数绵羊清单

热门文章

  1. 偏度与峰度的正态性分布判断
  2. 通俗篇:一文搞定矩阵相关概念及意义
  3. 对于SD-WAN安全的5个误区
  4. SSL协议安全系列:PKI体系中的证书吊销
  5. 关于fastlane自动化打包
  6. 多才多艺的移动式人形机器人iPal,担当起小朋友的“好家教”
  7. 潮州市云计算数据中心挂牌 粤东地区规模最大
  8. BZOJ 1192 鬼谷子的钱袋 数论
  9. php ids,PHP / MYSQL查询id“duplicate ids”
  10. java webservice 依赖_java开发webservice的几种方式