cf 786B. Legacy(线段树区间建图)

题目链接:传送门

题目思路:

  直接暴力连边,显然会超时,那么可以采用“源点”的建图思想,对于区间问题,可以利用线段树建图。

  建立一颗 inTree 和 outTree ,得:

  

 

     这样建图能保证初始时刻 [1,1] 可以到达 [1,2] ,[1,4] ,但是不能到达 其他叶子节点。

     对于区间 连接 单点,则从inTree 的区间 连接至outTree的单点;对于单点 连接 区间 则从inTree 的单点 连接至 outTree的区间 ;

     对于区间 连接 区间,则可以从 outTree 处理出来区间对应的节点集合,然后再 在inTree 中对应的区间 对集合中的点进行连边(也可以先处理inTree ,在outTree 中连边);

代码:(下面代码中,叶子节点是两棵树复用的)

  1 #include<bits/stdc++.h>
  2 #pragma GCC optimize(2)
  3 using namespace std;
  4 typedef long long LL;
  5 typedef unsigned long long uLL;
  6 typedef pair<int,int> pii;
  7 typedef pair<LL,LL> pLL;
  8 typedef pair<double,double> pdd;
  9 const int N=1e5+5;
 10 const int M=8e5+5;
 11 const LL inf=1e16;
 12 const LL mod=1e8+7;
 13 const double eps=1e-8;
 14 const long double pi=acos(-1.0L);
 15 #define ls (i<<1)
 16 #define rs (i<<1|1)
 17 #define fi first
 18 #define se second
 19 #define pb push_back
 20 #define eb emplace_back
 21 #define mk make_pair
 22 #define mem(a,b) memset(a,b,sizeof(a))
 23 LL read()
 24 {
 25     LL x=0,t=1;
 26     char ch;
 27     while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
 28     while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
 29     return x*t;
 30 
 31 }
 32 LL dis[N<<3];
 33 int cnt,vis[N<<3],n,s,q;
 34 struct node{ int l,r; };
 35 struct disx{
 36     LL x;int y;
 37     friend bool operator < (disx X,disx Y)
 38     {
 39         return X.x>Y.x;
 40     }
 41 };
 42 node c[N<<3];
 43 vector<pii> e[N<<3];
 44 inline void add(int u,int v,int w)
 45 {
 46     e[u].eb(v,w);
 47 }
 48 void buildin(int &now,int l,int r)
 49 {
 50     if(l==r) return (void)(now=l);
 51     now=++cnt;//printf("in = %d, %d %d\n",now,l,r);
 52     c[now].l=c[now].r=0;
 53     int mid=l+r>>1;
 54     buildin(c[now].l,l,mid);
 55     buildin(c[now].r,mid+1,r);
 56     add(c[now].l,now,0);
 57     add(c[now].r,now,0);
 58 }
 59 void buildout(int &now,int l,int r)
 60 {
 61     if(l==r) return (void)(now=l);
 62     now=++cnt;//printf("out = %d, %d %d\n",now,l,r);
 63     c[now].l=c[now].r=0;
 64     int mid=l+r>>1;
 65     buildout(c[now].l,l,mid);
 66     buildout(c[now].r,mid+1,r);
 67     add(now,c[now].l,0);
 68     add(now,c[now].r,0);
 69 }
 70 void updin(int now,int l,int r,int ll,int rr,int x,int y)
 71 {
 72     if(ll<=l&&r<=rr) return add(now,x,y);
 73     int mid=l+r>>1;
 74     if(mid>=ll) updin(c[now].l,l,mid,ll,rr,x,y);
 75     if(mid<rr) updin(c[now].r,mid+1,r,ll,rr,x,y);
 76 }
 77 void updout(int now,int l,int r,int ll,int rr,int x,int y)
 78 {
 79     if(ll<=l&&r<=rr) return add(x,now,y);
 80     int mid=l+r>>1;
 81     if(mid>=ll) updout(c[now].l,l,mid,ll,rr,x,y);
 82     if(mid<rr) updout(c[now].r,mid+1,r,ll,rr,x,y);
 83 }
 84 void dijk()
 85 {
 86     priority_queue<disx> q;
 87     for(int i=1;i<=cnt;i++) dis[i]=inf;
 88     q.push(disx{dis[s]=0,s});
 89     while(!q.empty())
 90     {
 91         int u=q.top().y;
 92         q.pop();
 93         if(vis[u]) continue;     //printf("u = %d\n",u);
 94         vis[u]=1;
 95         for(auto x:e[u])
 96         {
 97             //printf("%d -> %d\n",u,x.fi);
 98             int v=x.fi,w=x.se;
 99             if(dis[v]>dis[u]+w) q.push(disx{dis[v]=dis[u]+w,v});
100         }
101     }
102 }
103 int main()
104 {
105     n=read(),q=read(),s=read();
106     cnt=n;
107     int rt1,rt2;
108     buildin(rt1,1,n);
109     buildout(rt2,1,n);
110     //printf("r1 = %d , r2 = %d\n ",rt1,rt2);
111     for(int i=1;i<=q;i++)
112     {
113         int t=read();
114         if(t==1)
115         {
116             int v=read(),u=read(),w=read();
117             add(v,u,w);
118         }
119         else if(t==2)
120         {
121             int v=read(),l=read(),r=read(),w=read();
122             updout(rt2,1,n,l,r,v,w);
123         }
124         else
125         {
126             int v=read(),l=read(),r=read(),w=read();
127             updin(rt1,1,n,l,r,v,w);
128         }
129     }
130    // puts("...");
131     dijk();
132     for(int i=1;i<=n;i++)
133         printf("%lld ",dis[i]==inf?-1:dis[i]);
134     printf("\n");
135     return 0;
136 }
View Code

 

posted @ 2020-11-07 20:36  DeepJay  阅读(145)  评论(0编辑  收藏  举报