「珍贵历史资料鉴赏」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日,以「智联世界, ...
随机推荐
- js中的(function(){})()立即执行
( function(){-} )() 和 ( function (){-} () ) 是两种javascript立即执行函数的常见写法,要理解立即执行函数,需要先理解一些函数的基本概念. 函数声明. ...
- 【题解】Generator(UVA1358)
感觉我字符串和期望都不好-- 题目链接 题意 有 \(n\) 种字符,给定一个模式串 \(S\) ,一开始字符串为空,现在每次随机生成一个 1~n 的字符添加到字符串末尾,直到出现 \(S\) 停止, ...
- 开始是为了结束,结束是新的开始——NOI 2020 游记
Day 0 报道日 晚上的时候我们的教练给我们做考前动员.给我们讲:NOI的五个小时需要认真的规划,不能被T1打乱节奏.他让我们思考明天的策略,把可能出问题的地方都想清楚. 结果后来,宿管给我测体温, ...
- Angular:管道和自定义管道
①管道的使用,更多管道在angular官网上有 <p>全部转为大写:{{'hahahah' | uppercase}}</p> <p>保留两位小数:{{1.4555 ...
- 【Jenkins】环境配置及安装
下载地址: 国外官网:https://www.jenkins.io/zh/download/(版本最新) 国内镜像:http://mirrors.jenkins-ci.org/windows/ 清华镜 ...
- 【adb命令的使用,及logcat日志的分析】
实时记录日志: adb logcat -v time >D:\maimang.txtadb logcat -v threadtime > E:\Desktop\SSGame_log.txt ...
- ipad做windows副屏
利用iPad做windows的触摸显示屏 由于ios与windows不兼容,所以利用软件进行 主要的软件有三款:duet display:spacedesk:Splashtop Wired XDisp ...
- ssm的pom配置
<!--引入ssm依赖--> <!--常量和版本号 --> <properties> <!-- 文件编码 --> <project.build.s ...
- 从源码角度学习Java动态代理
前言 最近,看了一下关于RMI(Remote Method Invocation)相关的知识,遇到了一个动态代理的问题,然后就决定探究一下动态代理. 这里先科普一下RMI. RMI 像我们平时写的程序 ...
- tornado&django --- 分页
tornado 1,urls.py import config import os from views.view import IndexHadnler,SearchHadnler,Searchre ...