「珍贵历史资料鉴赏」CF786B 题解
写在前面
偶然翻到一篇 2019-08-07 18:58 写的未发布的题解。
给大家找点乐子玩。
正文
知识点:线段树优化建图
线段树优化建图
用于解决
类似 从 x 向区间[L,R]的
区间连边问题
原图:
1 2 3 4
向其中添加一系列虚点 ,
并将虚点与实点 , 虚点与虚点 连边,
将添加的边,的边权值设为0 之后:
o
/ \
o o
/ \ / \
1 2 3 4
形成一棵满二叉树
对于这棵满二叉树,
可以将其当作一棵线段树,
来进行一系列的操作:
对于 从 x 向区间[L,R]连边操作:
由于新添加的边权全为0
所以只需要将 x 与
"管辖" 着 [L,R] 区域的虚点连线即可
可以类比线段树的区间查询,
进行递归查询,要连接的边数,
由 R-L级别 ,转化为了log(R-L)级别对于 从 区间[L,R] 向 x 连边操作:
逆向操作
考虑反向连边即可
同时在初始化时,
也要注意 初始化反向的边对于 从x 向 y连边操作
直接连接即可
算法实现:
先进行两次 初始化建树操作
分别处理正向与反向的 ,
与虚点之间的连边,
将其设置为0.
然后对于每种连边操作,
按照上述法则,
将x与实点/虚点 连边
最后跑一遍最短路即可
注意的一些小点:
1.为了不影响实点之间的连边
虚点,即线段树上的点 的编号,
从n+1开始编号
#include<cstdio>
#include<queue>
#include<cstring>
#define ll long long
const int MARX = 3e5+10;
const ll INF = 0x3f3f3f3f3f3f3f3f;
//============================================
struct edge
{
int u,v,w,ne;
}e[MARX<<4];//各边
int n,q,start;//输入的初始变量
std:: queue <int> qu;//spfa的队列
int num,head[MARX];//建图变量
int cnt,root1,root2,ls[MARX],rs[MARX];//线段树变量 (ls为左儿子,rs为右儿子)
ll dis[MARX];//spfa 变量
//============================================
inline void add(int u,int v,int w)
{
e[++num].v=v,e[num].u=u,e[num].w=w;
e[num].ne=head[u],head[u]=num;
}
void build1(int &s,int l,int r)//初始化 从父亲向儿子的0边
{
if(l==r)//递归向下,直到 到达叶子部的 实点,
{
s=l;//实点的编号不变
return;
}
s = ++cnt;//更新当前虚点的编号
int mid = (l+r)>>1;
build1(ls[s],l,mid);//递归左右子树
build1(rs[s],mid+1,r);
add(s,ls[s],0);//向下连0边
add(s,rs[s],0);
}
void build2(int &s,int l,int r)//类比build1,进行反向连0边
{
if(l==r)
{
s=l;
return;
}
s = ++cnt;
int mid = (l+r)>>1;
build2(ls[s],l,mid);
build2(rs[s],mid+1,r);
add(ls[s],s,0);
add(rs[s],s,0);
}
int L,R;//要操作的左右区间
void updata(int s,int l,int r,int u,int w,int type)//s:当前点编号; l,r:当前点s管辖区间 ; type:操作的种类
{
if(L<=l && r<=R)//操作区间 包含 当前区间
{
if(type==2) add(u,s,w);//按照种类,进行连边操作.
else add(s,u,w);
return ;
}
int mid=(l+r)>>1;
if(L<=mid) updata(ls[s],l,mid,u,w,type);//递归进行操作
if(mid<R) updata(rs[s],mid+1,r,u,w,type);
}
void spfa(int start)//他死了
{
memset(dis,0x3f,sizeof(dis));
dis[start]=0;qu.push(start);
while(!qu.empty())
{
int u=qu.front(); qu.pop();
for(int i=head[u];i;i=e[i].ne)
{
int v=e[i].v,w=e[i].w;
if(dis[u]+w < dis[v])
{
dis[v]=dis[u]+w ;
qu.push(v);
}
}
}
}
//============================================
signed main()
{
scanf("%d%d%d",&n,&q,&start);
cnt=n;//为不影响实点之间的连边 , 虚点,从n+1开始编号
build1(root1,1,n),build2(root2,1,n);//初始化
for(int i=1;i<=q;i++)
{
int opt,u,v,w;
scanf("%d",&opt);
if(opt==1)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);//直接连接
}
else
{
scanf("%d%d%d%d",&u,&L,&R,&w);
updata((opt==2?root1:root2),1,n,u,w,opt);//按照种类,进行操作
}
}
spfa(start);
/*
for(int i=1;i<=n;i++)
for(int j=head[i];j;j=e[j].ne)
printf("%d %d %d\n",i,e[j].v,e[j].w);
*/
for(int i=1;i<=n;i++) printf("%lld ",dis[i]<INF?dis[i]:-1);
}
「珍贵历史资料鉴赏」CF786B 题解的更多相关文章
- 「GXOI / GZOI2019」简要题解
「GXOI / GZOI2019」简要题解 LOJ#3083. 「GXOI / GZOI2019」与或和 https://loj.ac/problem/3083 题意:求一个矩阵的所有子矩阵的与和 和 ...
- 精心整理「服务器Linux C/C++」 成长路程(附思维导图)
前言 我不是名校毕业,更没有大厂的背景,我只是一个毕业不到 2 年的普普通通的程序员,在摸爬滚打的工作这段时间里,深知了有一个「完整的知识体系」是非常重要的.当事人非常后悔没有在大学期间知道这个道理- ...
- [LOJ#6259]「CodePlus 2017 12 月赛」白金元首与独舞
[LOJ#6259]「CodePlus 2017 12 月赛」白金元首与独舞 试题描述 到河北省 见斯大林 / 在月光下 你的背影 / 让我们一起跳舞吧 うそだよ~ 河北省怎么可能有 Stalin. ...
- 「kuangbin带你飞」专题二十 斜率DP
layout: post title: 「kuangbin带你飞」专题二十 斜率DP author: "luowentaoaa" catalog: true tags: mathj ...
- 「kuangbin带你飞」专题二十二 区间DP
layout: post title: 「kuangbin带你飞」专题二十二 区间DP author: "luowentaoaa" catalog: true tags: - ku ...
- 「kuangbin带你飞」专题十九 矩阵
layout: post title: 「kuangbin带你飞」专题十九 矩阵 author: "luowentaoaa" catalog: true tags: mathjax ...
- 「kuangbin带你飞」专题十八 后缀数组
layout: post title: 「kuangbin带你飞」专题十八 后缀数组 author: "luowentaoaa" catalog: true tags: - kua ...
- 「kuangbin带你飞」专题十七 AC自动机
layout: post title: 「kuangbin带你飞」专题十七 AC自动机 author: "luowentaoaa" catalog: true tags: - ku ...
- WAIC | 奇点云携「酷炫AI应用」亮相2019世界人工智能大会
你是否还在疑惑“人工智能可否改变世界?” 那么,你该有一些危机感了. 机器视觉.自然语言处理.智能语音.机器人问诊.智慧驾驶……这些AI技术及应用早已渗入了我们日常生活的点滴. 29日,以「智联世界, ...
随机推荐
- linux常用快捷键总结
启动器:<super> 显示桌面:<super>D 文件管理器:<super>E 显示工作区:<super>S 打开终端:ctrl+alt+T 关闭窗口 ...
- Elements-of-Python_03_LanguageFeature
(内容包括Python语法概述,流程控制,条件表达式) 1 Python语法 1.1 Python的特点 Python是一种完全面向对象的.解释性的.可移植的.开源的脚本编程高级语言,具有丰富的库,允 ...
- 模拟数组 push() 方法
var array =[]; Array.prototype.push = function (){ for (var i=0; i< arguments.length; i++){ this[ ...
- ASP数据库连接方法语法总结
经常使用到有关数据库的操作.包括连接代码,SQL命令等等,又不曾刻意去记忆它们(我本人是不愿意去记这东东),所以常常在用到的时候又去查书本,翻来翻去.一些比较少用的数据库还不一定能顺利找到,所以现在把 ...
- JOISC2020 自闭记
以下是我考场上的思路,很多题都不是正解.对于某些题目,我们使用<代码部落>中的题解,希望大家能够看懂 JOISC2020 Round1 自闭记 T1 11 pts 算法:考虑\(DP\). ...
- pyppeteer 登录一般网站 并利用 http方法获取登录页面的验证码
主函数 新建浏览器,进行登录,由于验证码的识别准确率不是百分之百,需要多次尝试. async def main(self, username, pwd, url): # 定义main协程函数, log ...
- gulp-sourcemaps的用法
1.项目文件夹中,安装gulp-sourcemaps插件 npm install --save gulp-sourcemaps 2.gulpfile.js文件,导入要用到的插件. 如: // 引入gu ...
- STL—— 容器(vector)begin() 与 rbegin() , end() 与 rend()
1. Vector 迭代器首地址与尾地址 begin() 和 end() 在代码中可以将迭代器用作参数的位置可以使用 begin() 和 end() 获取地址,如下代码: 1 #include &l ...
- 如何将 Dapper 换成 SqlSuagr ORM
为什么要写这篇文章 因数我看到很多人虽然用着SqlSugar,但是同时也用着Dapper,因为SqlSugar兼容了Dapper所有API,所以既然你用了SqlSugar那么就没有必要在同一个项目中使 ...
- 查询是否sci或者ei收录
1,如果查文章是不是被SCI检索:进入ISI Web of Knowledge,选择Web of Science 数据库,进行查询:2,如果查文章是不是被EI检索:进入EI Village, 选择Co ...