首页 > 其他分享 >【学习笔记】线段树优化建图

【学习笔记】线段树优化建图

时间:2022-08-14 22:11:21浏览次数:50  
标签:rt int 线段 mid 笔记 建图 long rson dis

先开坑,有时间再说。

例题

CF786B Legacy

Code

//线段树优化建图,从寒假一直咕到暑假 
//之前觉得难得不行,现在看还是挺好理解的 
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int MAXN = 2e6 + 10;
int n, m, s, cnt, root_in, root_out;
int head[MAXN];
long long dis[MAXN];
bool used[MAXN];
queue<int> q;

struct Edge{
    int to, next;
    long long dis;
}e[MAXN];

inline void Add(int u, int v, long long w){
    e[++cnt].to = v;
    e[cnt].dis = w;
    e[cnt].next = head[u];
    head[u] = cnt;
}

struct Segment_Tree{
    int tot;

    struct Tree{
        int lson, rson;
    }tr[MAXN];

    #define lson(x) tr[x].lson
    #define rson(x) tr[x].rson

    void Build_out(int &rt, int l, int r){
        if(l == r){
            rt = l;
            return;
        }

        rt = ++tot;
        int mid = (l + r) >> 1;
        Build_out(lson(rt), l, mid);
        Build_out(rson(rt), mid + 1, r);

        Add(rt, lson(rt), 0);
        Add(rt, rson(rt), 0);
    }

    void Build_in(int &rt, int l, int r){
        if(l == r){
            rt = l;
            return;
        }

        rt = ++tot;
        int mid = (l + r) >> 1;
        Build_in(lson(rt), l, mid);
        Build_in(rson(rt), mid + 1, r);

        Add(lson(rt), rt, 0);
        Add(rson(rt), rt, 0);
    }

    void Update_out(int rt, int l, int r, int L, int R, int u, int w){
        if(L >= l && R <= r){
            Add(u, rt, w);
            return;
        }

        int mid = (L + R) >> 1;
        if(l <= mid) Update_out(lson(rt), l, r, L, mid, u, w);
        if(r > mid) Update_out(rson(rt), l, r, mid + 1, R , u, w);
    }

    void Update_in(int rt, int l, int r, int L, int R, int v, int w){
        if(L >= l && R <= r){
            Add(rt, v, w);
            return;
        }

        int mid = (L + R) >> 1;
        if(l <= mid) Update_in(lson(rt), l, r, L, mid, v, w);
        if(r > mid) Update_in(rson(rt), l, r, mid + 1, R, v, w);
    }
}S;

void Spfa(int x){
    memset(used, 0, sizeof(used));
    memset(dis, 0x3f, sizeof(dis));

    dis[x] = 0;
    q.push(x);
    used[x] = true;

    while(!q.empty()){
        int k = q.front();
        q.pop();
        used[k] = false;

        for(register int i = head[k]; i; i = e[i].next){
            int v = e[i].to;

            if(dis[v] > dis[k] + e[i].dis){
                dis[v] = 1LL * dis[k] + e[i].dis;
                if(!used[v]){
                    q.push(v);
                    used[v] = true;
                }
            }
        }
    }
}

inline long long read(){
    long long x = 0, f = 1;
    char c = getchar();

    while(c < '0' || c > '9'){
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9'){
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }

    return x * f;
}

int main(){
    n = read(), m = read(), s = read();
    S.tot = n;
    S.Build_out(root_out, 1, n);
    S.Build_in(root_in, 1, n);
    for(register int i = 1; i <= m; i++){
        int opt;
        opt = read();

        if(opt == 1){
            int u, v, w;
            u = read(), v = read(), w = read();
            Add(u, v, w);
        }
        else if(opt == 2){
            int u, l, r, w;
            u = read(), l = read(), r = read(), w = read();
            S.Update_out(root_out, l, r, 1, n, u, w);
        }
        else{
            int v, l, r, w;
            v = read(), l = read(), r = read(), w = read();
            S.Update_in(root_in, l, r, 1, n, v, w);
        }
    }

    Spfa(s);

    for(register int i = 1; i <= n; i++){
        if(dis[i] == 4557430888798830399) printf("-1 ");
        else printf("%lld ", dis[i]);
    }

    return 0;
}

标签:rt,int,线段,mid,笔记,建图,long,rson,dis
From: https://www.cnblogs.com/TSTYFST/p/16586525.html

相关文章

  • BOSC实习笔记
    2022.7.251.所谓-wall是一个编译选项,让编译器对你的代码提出尽可能多的警告 2022.7.261.cd不是程序,所以唯一没有没有manpage的指令2.管道A|B将A进程的标准输出连......
  • TypeScript 笔记(二)
    1.元组含义:限定了数组元素的数量,且规定了具体每个数组元素的数据类型的数据被称为元组//元组vare_list:[number,string]=[1,'2']//创建元组类型typeEList=[n......
  • 欧拉路径学习笔记
    \(\bigstar\)欧拉路径若\(G=(V,\E)\)中的一条路径包含了\(E\)中的所有边且不重复,则称其为欧拉路径(\(\textbf{EulerianPath}\))。若该路径的起点与终点相同,则称其......
  • 【SpringBoot】学习笔记-MVC
     自动配置了ViewResolver,就是我们之前学习的SpringMVC的视图解析器;即根据方法的返回值取得视图对象(View),然后由视图对象决定如何渲染(转发,重定向)。我们去看看这里的源码......
  • HTML+CSS笔记
    HTML(超文本标记语言)w3c标准:结构化标准语言(XHTML、XML)表现标准语言:(CSS)行为标准:(DOM、ECMScrit)一、基本标签块级标签:无论多少内容,在网页独占一行,前后换行标题标签:......
  • P6144 [USACO20FEB]Help Yourself P(DP+线段树)
    P6144[USACO20FEB]HelpYourselfP将线段按照了\(r\)排序,设右端点为\(r\)的答案为\(f_r\),发现这样转移非常困难。\(\color{yellow}{\bigstar\texttt{Trick}}\):区间......
  • SP1557 GSS2 - Can you answer these queries II(离线 线段树)
    SP1557GSS2-CanyouanswerthesequeriesII\(\bigstar\texttt{Hint}\):遇到去重的问题,我们通常考虑离线询问后处理。可以枚举右端点,将询问存储在右端点,考虑用数据结......
  • 【Spring5学习笔记】Bean管理:
    Bean管理:(1)Bean管理指的是两个操作(2)Spring创建对象(3)Spring注入属性Bean管理操作有两种方式:1、基于xml配置文件方式(1)在Spring配置文件中,使用bean标签,标签里添加对应的属......
  • CF464E The Classic Problem(线段树 最短路)
    CF464ETheClassicProblem\(\bigstar\texttt{Hint}\):发现没有什么好的突破口?为什么不想想怎样才能实现题目中\(2^x\)的加减法呢?可见每次加减法,我们要做的是将添加的......
  • docker swarm容器编排学习笔记
    1、介绍DockerSwarm 和DockerCompose一样,都是Docker官方容器编排项目不同点:DockerCompose是一个在单个服务器或主机上创建多个容器的工具,DockerSwarm则可以......