首页 > 其他分享 >线段树优化建图

线段树优化建图

时间:2023-12-01 21:45:18浏览次数:30  
标签:opt dui kd int 线段 建图 优化 dis

问题
CF786B
给定一个\(n\)个点,\(m\)次连边的有向图,有三种连边(均有边权)方式:
1.\(u\to v\),一条\(u\)指向\(v\)的连边。
2.\(u\to [l,r]\),\(u\)向在区间\([l,r]\)的点分别连一条边。
3.\([l,r]\to v\),在区间\([l,r]\)的点向\(v\)分别连一条边。
问从\(1\)点出发,到各个点的最短路。
思路:
这里是用线段树优化建图trick,就是如果每次2和3的操作\([l,r]\)都是\([1,n]\),建边的数量就是\(n\times m\)。这里类比求区间和,可以使用线段树,将一个点向一个线段树上的点连边,每次连\(\log_{2} n\)条边。线段树上的点再连上它在线段树上的子节点,叶子节点就直接连图上的对应点,就能与2和3操作等效。注意:要建一棵自上而下的线段树和一颗自下而上的线段树。
代码:

#include<iostream>
#include<vector>
#include<queue>
#define int long long
#define INF 1000000000000000000
using namespace std;
int kd(){
	int x=0,f=1;
	char a=getchar();
	while(a<'0'||a>'9'){
		if(a=='-'){
			f=-1;
		}
		a=getchar();
	}
	while(a>='0'&&a<='9'){
		x=x*10+a-'0';
		a=getchar();
	}
	return x*f;
}
int n,q,s;
struct node{
	int l,r;
}tree[400010];
struct nod{
	int to;
	int nxt;
	int val;
}edge[4000010];
int head[1000010],tot;
void addedge(int u,int v,int w){
	edge[++tot].to=v;
	edge[tot].nxt=head[u];
	edge[tot].val=w;
	head[u]=tot;
}
void build(int i,int l,int r){
	tree[i].l=l;
	tree[i].r=r;
	if(l==r){
		addedge(i,l+8*n,0);
		addedge(l+8*n,i+4*n,0);
		return ;
	}
	int mid=(l+r)/2;
	addedge(i,i*2,0);
	addedge(i,i*2+1,0);
	addedge(i*2+4*n,i+4*n,0);
	addedge(i*2+1+4*n,i+4*n,0);
	build(i*2,l,mid);
	build(i*2+1,mid+1,r);
	return ;
}
void search1(int i,int l,int r,int k,int w){
	if(tree[i].l>=l&&tree[i].r<=r){
		addedge(k+8*n,i,w);
		return ;
	}
	if(tree[i*2].r>=l){
		search1(i*2,l,r,k,w);
	}
	if(tree[i*2+1].l<=r){
		search1(i*2+1,l,r,k,w);
	}
}
void search2(int i,int l,int r,int k,int w){
	if(tree[i].l>=l&&tree[i].r<=r){
		addedge(i+4*n,k+8*n,w);
		return ;
	}
	if(tree[i*2].r>=l){
		search2(i*2,l,r,k,w);
	}
	if(tree[i*2+1].l<=r){
		search2(i*2+1,l,r,k,w);
	}
}
int dis[1000010];
bool vis[1000010];
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > dui;
void dij(){
	dui.push(make_pair(0,8*n+s));
	while(!dui.empty()){
		int u=dui.top().second;
		dui.pop();
		if(vis[u]==1){
			continue;
		}
		vis[u]=1;
		for(int i=head[u];i;i=edge[i].nxt){
			int v=edge[i].to;
			if(vis[v]==1){
				continue;
			}
			if(dis[v]>dis[u]+edge[i].val){
				dis[v]=dis[u]+edge[i].val;
				dui.push(make_pair(dis[v],v));
			}
		}
	}
}
signed main(){
	cin>>n>>q>>s;
	build(1,1,n);
	while(q--){
		int opt;
		opt=kd();
		if(opt==1){
			int u,v,w;
			u=kd();v=kd();w=kd();
			addedge(u+8*n,v+8*n,w);
		}
		if(opt==2){
			int u,l,r,w;
			u=kd();l=kd();r=kd();w=kd();
			search1(1,l,r,u,w); 
		}
		if(opt==3){
			int v,l,r,w;
			v=kd();l=kd();r=kd();w=kd();
			search2(1,l,r,v,w);
		}
	}
	for(int i=1;i<=9*n;i++){
		dis[i]=INF;
	}
	dis[8*n+s]=0;
	dij();
	for(int i=1;i<=n;i++){
		if(dis[8*n+i]==INF){
			printf("-1 ");
		}
		else{
			printf("%lld ",dis[8*n+i]);
		}
	}
	return 0;
}

标签:opt,dui,kd,int,线段,建图,优化,dis
From: https://www.cnblogs.com/z-2-we/p/17870919.html

相关文章

  • # yyds干货盘点 # input()这个有没有什么优化的办法可以记住前面的数据?
    大家好,我是皮皮。一、前言前几天在Python最强王者交流群【哎呦喂 是豆子~】问了一个Python数据输入的问题,一起来看看吧。问题描述:大佬们 在咨询一个问题 就是这个input 涉及多个 然后可能敲到最后一个数据敲错了又得重新敲一遍这个有没有什么优化的办法可以记住前面的数......
  • vue3+vite项目优化静态资源使用云存储
    项目中的问题1.当我们在维护自己的博客或者自己的网站的时候没有特别好的服务器就会响应特别的慢2.当我们项目特别大的时候也会首屏加载特别慢而且vue项目打包后的js文件特别的庞大还要加载各种资源就会特别的卡顿3.当我们项目中用到了一些3D效果各种3D资源部特别的大的时......
  • 案例解析关于ArkUI框架中ForEach的潜在陷阱与性能优化
    本文分享自华为云社区《深入解析ForEach的潜在陷阱与性能优化:错误用法与性能下降的案例分析》,作者:柠檬味拥抱。在ArkUI框架中,ForEach接口是基于数组类型数据进行循环渲染的强大工具。它需要与容器组件搭配使用,并能够根据数据源动态生成相应的子组件。以下是对ForEach接口的详细......
  • 基于AI的架构优化:创新数据集构造法提升Feature envy坏味道检测与重构准确率
    本文分享自华为云社区《华为云基于AI实现架构坏味道重构取得业界突破,相应文章已被软工顶会FSE2023收录》,作者:华为云软件分析Lab。基于AI技术实现架构坏味道检测与重构建议是当前业界比较流行的做法,但此做法往往存在一个通病,即训练数据集的质量问题,如何构建大规模、高质量的训练......
  • class-dump 混淆加固、保护与优化原理
    ​ class-dump混淆加固、保护与优化原理进行逆向时,经常需要dump可执行文件的头文件,用以确定类信息和方法信息,为hook相关方法提供更加详细的数据.class-dump的主要用于检查存储在MachO文件的Objective-C中的运行时信息,为类,类别和协议生成声明信息,与tool-ov命令产生的信息相......
  • 测试环境使用问题及其优化对策实践
    1背景及问题G.J.Myers在<软件测试技巧>中提出:测试是为了寻找错误而运行程序的过程,一个好的测试用例是指很可能找到迄今为止尚未发现的错误的测试,一个成功的测试是揭示了迄今为止尚未发现的错误的测试。对于新手来说,日常测试用例设计时,很少用到系统的方法论,大多是根据产品需求......
  • Linux进行网络带宽优化
    如何使用Linux进行网络带宽优化网络带宽的优化是提高网络传输速度和质量的关键。在Linux系统中,有许多方法可以帮助我们优化网络带宽调整内核参数调整Linux内核参数可以改善网络性能。a)修改TCP窗口大小TCP窗口大小决定了发送和接收数据的速度。通过增加TCP窗口大小,可以加快网络......
  • 像使用stl一样使用线段树 ——AtCoder Library(转载https://zhuanlan.zhihu.com/p/459
    地址:https://zhuanlan.zhihu.com/p/459579152 我这里翻译一下官方的文档。首先需要满足几个性质。(注意 ∗ 是个操作,不是单纯的一个乘号)1)操作满足结合律即 (a∗b)∗c=a∗(b∗c)2)操作需要有个幺元(基本元/单位元)a∗e=e∗a=a如果你有这个一个序列S,长度为N ,接下......
  • 让人头皮发麻的Android 性能优化版块,这样简单就学会了?
    前言对现如今的Android开发来讲,不管是在面试还是在日常工作中,性能优化都是一个绕不开的话题。以下这些场景,大家或多或少都有遇见过:当你很努力地优化了应用的性能后,用户依然不断抱怨应用卡顿、启动速度慢等问题。当老大给到你性能优化的KPI,内存要降多少,包体积要减多少时,直接头痛到......
  • 专门针对工业电机控制进行优化XCZU1CG-2SFVA625I、XCZU1CG-2SFVA625E(SoC FPGA)
    CG设备典型应用:传感器处理和融合电机控制低成本超声波交通工程概述:Zynq®UltraScale+™MPSoC器件不仅提供64位处理器可扩展性,同时还将实时控制与软硬件引擎相结合,支持图形、视频、波形与数据包处理。三个不同变体包括双应用处理器(CG)器件、四核应用处理器和GPU(EG)器件......