CF786B Legacy (FIG segment tree construction optimized shortest +)

In a collective camp qbxt do

Solution to a problem in the field, and basically all OIer two segments of the tree

God OIer TM and consistent thinking we Luan - only a segment tree, similar to the idea of ​​a one-dimensional hierarchical diagram, the second layer with the first layer node number corresponding to that of the first layer node ID + NUM, but seemingly normal score particles thinking, because meet lson = k << 1, rson = k << 1 | 1, and the segment tree is generally high similarity.

As to why the division or layering pieces, want easy to understand tree side (secondary side) must be bidirectional (for it takes out information ancestor node), but regardless of if or layered pieces, then seek out the shortest path is not obvious 0 is yet QwQ

Therefore, if the hierarchical parent to child should be one sub-leaf nodes should be connected by the parent between the other layer, the two layers

Further processing issue leaf node, YoOXiii Pride205 and the picture is projected onto the i-th node of the tree node i + n (n is the number of original junction point)

They see this code (in fact, I did not carefully study clearly their approach), where no stealing (theft crime w), to look to find their own

Since I sit one and they do not, there is no exchange of ideas when you want, so I did not write, I built the first layer in accordance with the number of general tree line, so a bit easier. Then the original node directly to the leaf node mapping to (open a pos array) (know szsz46 is so written, original thinking Lu'an OIer synchronization with the space does not change QwQ)

then......

The bar code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<iostream>
#define NUM 1000000
#define maxn 100005<<5
//这两个范围要调好 
#define int long long
using namespace std;
typedef long long ll;

inline void input(ll &x){
    ll ans=0,f=1;
    char c=getchar();
    while(c>'9'||c<'0'){
        if(c=='-')f=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        ans=ans*10+c-48;
        c=getchar();
    }
    x=ans*f;
}

inline void output(ll x){
    if(x<0)x=-x,putchar('-');
    if(x>9)output(x/10);
    putchar(x%10+48);
}

inline void writeln(ll x){
    output(x);
    putchar('\n');
}

int n,m,s,head[maxn],c[maxn],pos[maxn],vis[maxn],dis[maxn],cnt;

//pos:题中结点在树上的编号 

struct edge{
    int v,w,next;
}e[maxn];

struct node{
    int dis,u;
    bool operator<(const node &x)const{return x.dis<dis;}
};

inline void add(int u,int v,int w){
    e[++cnt].v=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt;
//  cout<<u<<' '<<v<<' '<<w<<endl;
}

inline void build(int k,int l,int r){
    if(l==r){
        pos[l]=k;
        add(k+NUM,k,0);
        add(k,k+NUM,0);
        return;
    }
    int mid=(l+r)>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
    add(k<<1,k,0);
    add(k<<1|1,k,0);
    add(k+NUM,(k<<1)+NUM,0);//调了一个小时:加括号;在括号外加NUM而不是给k加NUM 
    add(k+NUM,(k<<1|1)+NUM,0);
}

inline void add(int k,int l,int r,int xl,int xr,int from,int w,int opt){
    if(xl<=l&&r<=xr){
        if(opt==2)add(from,k+NUM,w);
        else if(opt==3)add(k,from,w);
        return;
    }
    int mid=(l+r)>>1;
    if(xl<=mid)add(k<<1,l,mid,xl,xr,from,w,opt);
    if(xr>=mid+1)add(k<<1|1,mid+1,r,xl,xr,from,w,opt);
}

priority_queue<node> q;

inline void dijkstra(){
    s=pos[s];
    q.push((node){0,s});
    dis[s]=0;
    while(!q.empty()){
        int x=q.top().u;
        q.pop();
        if(vis[x])continue;
        vis[x]=1;
        for(int i=head[x];i!=-1;i=e[i].next){
            int y=e[i].v;
            if(!vis[y]&&dis[y]>dis[x]+e[i].w){
                dis[y]=dis[x]+e[i].w;
                q.push((node){dis[y],y});//想不到吧,这一行打错使我调了半个小时 
            }
        }
    }
    s<<=1;
    if(s>=1)dijkstra();
}

signed main(){
    memset(head,-1,sizeof(head));
    memset(dis,127,sizeof(dis));
    memset(vis,0,sizeof(vis));
    input(n);input(m);input(s);
    build(1,1,n);
    for(int i=1;i<=m;i++){
        int opt;
        input(opt);
        if(opt==1){
            int u,v,w;
            input(u);input(v);input(w);
            add(pos[u],pos[v],w);
        }
        else if(opt==2){
            int u,l,r,w;
            input(u);input(l);input(r);input(w);
            add(1,1,n,l,r,pos[u],w,opt);
        }
        else if(opt==3){
            int u,l,r,w;
            input(u);input(l);input(r);input(w);
            add(1,1,n,l,r,pos[u],w,opt);
        }
    }
    dijkstra();
//  for(int i=1;i<=4*n;i++)cout<<i<<' '<<dis[i]<<endl;
    for(int i=1;i<=n;i++)output(dis[pos[i]]<=1e15?dis[pos[i]]:-1),putchar(' ');
}

Guess you like

Origin www.cnblogs.com/Y15BeTa/p/11318060.html