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

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


题目传送门
在这里插入图片描述
由于本题的数据达到了1e5,所以如果直接全部暴力连边的话会达到 O ( n 2 ) 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;
}

已标记关键词 清除标记
课程简介: 历经半个多月的时间,Debug亲自撸的 “企业员工角色权限管理平台” 终于完成了。正如字面意思,本课程讲解的是一个真正意义上的、企业级的项目实战,主要介绍了企业级应用系统中后端应用权限的管理,其中主要涵盖了六大核心业务模块、十几张数据库表。 其中的核心业务模块主要包括用户模块、部门模块、岗位模块、角色模块、菜单模块和系统日志模块;与此同时,Debug还亲自撸了额外的附属模块,包括字典管理模块、商品分类模块以及考勤管理模块等等,主要是为了更好地巩固相应的技术栈以及企业应用系统业务模块的开发流程! 核心技术栈列表: 值得介绍的是,本课程在技术栈层面涵盖了前端和后端的大部分常用技术,包括Spring Boot、Spring MVC、Mybatis、Mybatis-Plus、Shiro(身份认证与资源授权跟会话等等)、Spring AOP、防止XSS攻击、防止SQL注入攻击、过滤器Filter、验证码Kaptcha、热部署插件Devtools、POI、Vue、LayUI、ElementUI、JQuery、HTML、Bootstrap、Freemarker、一键打包部署运行工具Wagon等等,如下图所示: 课程内容与收益: 总的来说,本课程是一门具有很强实践性质的“项目实战”课程,即“企业应用员工角色权限管理平台”,主要介绍了当前企业级应用系统中员工、部门、岗位、角色、权限、菜单以及其他实体模块的管理;其中,还重点讲解了如何基于Shiro的资源授权实现员工-角色-操作权限、员工-角色-数据权限的管理;在课程的最后,还介绍了如何实现一键打包上传部署运行项目等等。如下图所示为本权限管理平台的数据库设计图: 以下为项目整体的运行效果截图: 值得一提的是,在本课程中,Debug也向各位小伙伴介绍了如何在企业级应用系统业务模块的开发中,前端到后端再到数据库,最后再到服务器的上线部署运行等流程,如下图所示:
©️2020 CSDN 皮肤主题: 撸撸猫 设计师:设计师小姐姐 返回首页