zoukankan      html  css  js  c++  java
  • CF786B/CF787D

    线段树优化建图板子题

    首先暴力建图显然是不可取的,但是我们发现建图要求是点和区间之间的问题,所以考虑用线段树优化

    但是怎么优化呢?

    如果用一棵线段树很难处理同时出边和入边,因此我们考虑用两棵线段树(类似拆点),一棵线段树作为起点,另一棵线段树作为终点,然后在两棵线段树之间连边即可

    这样的话连边的方式也就是起点线段树中一个节点(代表一个点或一段区间)向终点线段树中一个节点(代表一个点或一段区间),起点线段树从下向上连边,终点线段树从上向下连边,终点线段树叶节点向对应起点线段树叶节点连边即可

    贴代码:

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #define ll long long
    #define rt1 (rt<<1)
    #define rt2 ((rt<<1)|1)
    using namespace std;
    struct Edge
    {
        int nxt;
        int to;
        ll val;
    }edge[5000005];
    struct node
    {
        int p;
        ll v;
        node (){}
        node (int x,ll y):p(x),v(y){}
        friend bool operator < (node a,node b)
        {
            return a.v>b.v;
        }
    };
    int pos1[100005];
    int pos2[100005];
    int head[800005];
    bool vis[800005];
    ll dis[800005];
    int cnt=1;
    int n,q,s;
    void add(int l,int r,ll w)
    {
        edge[cnt].nxt=head[l];
        edge[cnt].to=r;
        edge[cnt].val=w;
        head[l]=cnt++;
    }
    void buildtree1(int rt,int l,int r)
    {
        if(l==r){pos1[l]=rt;return;}
        int mid=(l+r)>>1;
        buildtree1(rt1,l,mid),buildtree1(rt2,mid+1,r);
        add(rt1,rt,0),add(rt2,rt,0);
    }
    void buildtree2(int rt,int l,int r)
    {
        if(l==r){pos2[l]=rt+4*n;return;}
        int mid=(l+r)>>1;
        buildtree2(rt1,l,mid),buildtree2(rt2,mid+1,r);
        add(rt+4*n,rt1+4*n,0),add(rt+4*n,rt2+4*n,0);
    }
    template <typename T>inline void read(T &x)
    {
        T f=1,c=0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
        x=f*c;
    }
    void query_add1(int rt,int l,int r,int lq,int rq,int v,ll w)//区间->点
    {
        if(l>=lq&&r<=rq){add(rt,v,w);return;}
        int mid=(l+r)>>1;
        if(lq<=mid)query_add1(rt1,l,mid,lq,rq,v,w);
        if(rq>mid)query_add1(rt2,mid+1,r,lq,rq,v,w);
    }
    void query_add2(int rt,int l,int r,int lq,int rq,int v,ll w)//点->区间
    {
        if(l>=lq&&r<=rq){add(v,rt+4*n,w);return;}
        int mid=(l+r)>>1;
        if(lq<=mid)query_add2(rt1,l,mid,lq,rq,v,w);
        if(rq>mid)query_add2(rt2,mid+1,r,lq,rq,v,w);
    }
    void diji()
    {
        memset(dis,0x3f,sizeof(dis));
        dis[pos1[s]]=dis[pos2[s]]=0;
        priority_queue <node> Q;
        Q.push(node(pos1[s],0));
        while(!Q.empty())
        {
            node u=Q.top();
            Q.pop();
            if(vis[u.p])continue;
            vis[u.p]=1;
            for(int i=head[u.p];i;i=edge[i].nxt)
            {
                int to=edge[i].to;
                if(dis[to]>dis[u.p]+edge[i].val&&!vis[to])dis[to]=dis[u.p]+edge[i].val,Q.push(node(to,dis[to]));
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(dis[pos2[i]]==0x3f3f3f3f3f3f3f3fll)printf("-1 ");
            else printf("%lld ",dis[pos2[i]]);
        }
        printf("
    ");
    }
    int main()
    {
        read(n),read(q),read(s);
        buildtree1(1,1,n),buildtree2(1,1,n);
        for(int i=1;i<=n;i++)add(pos2[i],pos1[i],0);
        while(q--)
        {
            int typ;
            ll w;
            read(typ);
            if(typ==1)
            {
                int st,ed;
                read(st),read(ed),read(w);
                add(pos1[st],pos2[ed],w);
            }else if(typ==2)
            {
                int lq,rq,st;
                read(st),read(lq),read(rq),read(w);
                query_add2(1,1,n,lq,rq,pos1[st],w);
            }else
            {
                int lq,rq,ed;
                read(ed),read(lq),read(rq),read(w);
                query_add1(1,1,n,lq,rq,pos2[ed],w);
            }
        }
        diji();
        return 0;
    }
  • 相关阅读:
    [转]asp.net页面缓存技术
    UL和LI在div中的高度的IE6下兼容性
    jquery制作的横向图片滚动带横向滚动条TackerScroll
    电脑可以上网,但是qq登陆不上去?
    Introduction to discrete event system学习笔记4.6
    Introduction to Discrete event system学习笔记4.9
    Introduction to discrete event systemsstudy 4.5
    Symbolic synthesis of obserability requirements for diagnosability B.Bittner,M.Bozzano,A.Cimatti,and X.Olive笔记4.16
    Introduction to discrete event system学习笔记4.8pm
    Introduction to discrete event system学习笔记 4.8
  • 原文地址:https://www.cnblogs.com/zhangleo/p/11131125.html
Copyright © 2011-2022 走看看