• [CF787D]Legacy


    NOId1t1有这种线段树优化建边的部分分,然后发现还不会。。。

    思想就是化为两棵线段树,一棵代表出一棵代表入。每棵树内部就正常那么连边,然后点连到区间就相当于把区间按线段树拆法拆成log个区间,内部yy一下就行了。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<ll,int> P;
    const int N=500000;
    const ll inf=1e16;
    inline int read(){
        int r=0,c=getchar();
        while(!isdigit(c))c=getchar();
        while(isdigit(c))r=r*10+c-'0',c=getchar();
        return r;
    }
    struct Edge{
        int to,nxt,w;
    }e[N<<2];
    int n,m,S;
    int head[N<<2],cnt=1;
    void add(int u,int v,int w){
        e[cnt]=(Edge){v,head[u],w};
        head[u]=cnt++;
    }
    struct Node{
        int l,r;
    }T[N<<2];
    #define L T[o].l
    #define R T[o].r
    #define M (L+R>>1)
    #define ls o<<1
    #define rs o<<1|1
    void build(int o,int l,int r){
        T[o]=(Node){l,r};
        if(l==r){
            add(o,o+N,0);
            add(o+N,o,0);
            return;
        }
        build(ls,L,M);
        build(rs,M+1,R);
        add(ls,o,0);add(o+N,(ls)+N,0);
        add(rs,o,0);add(o+N,(rs)+N,0);
    }
    int ql,qr,tmp,ww,tp;
    void find(int o){
        if(ql<=L&&R<=qr){
            if(tp<3)tmp=o;
            else tmp=o+N;
            return;
        }
        if(ql<=M)find(ls);
        if(qr>M) find(rs);
    }
    void upd(int o){
        if(ql<=L&&R<=qr){
            if(tp<3)add(tmp,o+N,ww);
            else add(o,tmp,ww);
            return;
        }
        if(ql<=M)upd(ls);
        if(qr>M) upd(rs);
    }
    ll dis[N<<2];bool vis[N<<2];
    priority_queue<P,vector<P>,greater<P> >q;
    void dij(){
        fill(dis,dis+(N<<1),inf);
        ql=qr=S;tp=1;find(1);S=tmp;
        q.push(P(dis[S]=0,S));
        while(!q.empty()){
            P x=q.top();q.pop();
            ll d=x.first;int u=x.second;
            if(vis[u])continue;vis[u]=1;
            for(int i=head[u];i;i=e[i].nxt){
                int v=e[i].to,w=e[i].w;
                if(d+w<dis[v]){
                    dis[v]=d+w;
                    q.push(P(dis[v],v)); 
                }
            }
        }
    }
    void init(){
        n=read();m=read();
        S=read();
        build(1,1,n);
        while(m--){
            tp=read();
            int u,v,l,r;
            if(tp==1){
                u=read();v=read();ww=read();
                ql=qr=u;find(1);
                ql=qr=v;upd(1);
            }
            else{
                u=read();l=read(),r=read();ww=read();
                ql=qr=u;find(1);
                ql=l,qr=r;upd(1);
            }
        }
    }
    void prt(int o){
        if(L==R){
            if(dis[o+N]==inf)dis[o+N]=-1;
            printf("%lld ",dis[o+N]);
            return;
        }
        prt(ls);prt(rs);
    }
    int main(){
        init();
        dij();
        prt(1);
    }
  • 相关阅读:
    PHPMyAdmin Docker
    Appium环境搭建-Mac版本
    上传项目到GitHub遇到的错误
    上传项目到GitHub(总结)
    C++ 简单代码,语法参照
    vs2010学习
    线性拟合-实验报告
    我的图形学程序
    网页版 连连看 html5实现
    带无线功能的笔记本 配置无线局域网 共享上网
  • 原文地址:https://www.cnblogs.com/orzzz/p/11223093.html
Copyright © 2020-2023  润新知