zoukankan      html  css  js  c++  java
  • bzoj 3073 [Pa2011]Journeys ——线段树优化连边

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3073

    建两棵线段树,一棵孩子向父亲连边,是走出去的;一棵父亲向孩子连边,是走进来的。

    注意第二棵线段树的叶子向第一棵线段树的叶子连边。

    在树上节点间连边的时候,不是 log^2 地直接连,而要新建一个节点作中转点,这样边数就是 2*log 的;连向中转点和连出去的边一部是0一部是1或者全是0.5即可。

    注意连无向边。两种方向当然是两个中转点。

    边数 3e7 似乎还是小。但能过。更大就开不下了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int N=4e6+5,M=3e7+5,K=5e5+5;
    int n,m,p,tot,hd[N],xnt,to[M],nxt[M],w[M],ls[K<<2],rs[K<<2],dis[N];
    int rt,d0[K],d1[K];
    bool vis[N];
    priority_queue<pair<int,int> > q;
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    void wrt(int x)
    {
      if(x<0)putchar('-'),x=-x;
      if(x<10){putchar(x+'0');return;}
      wrt(x/10); putchar(x%10+'0');
    }
    void add(int x,int y,int z)
    {
      to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;w[xnt]=z;
    }
    void build(int l,int r,int cr,bool fx)
    {
      if(l==r)
        {
          if(!fx)d0[l]=cr;
          else d1[l]=cr,add(cr,d0[l],0);
          return;
        }
      int mid=l+r>>1;
      ls[cr]=++tot; build(l,mid,ls[cr],fx);
      rs[cr]=++tot; build(mid+1,r,rs[cr],fx);
      if(fx)add(cr,ls[cr],0),add(cr,rs[cr],0);
      else add(ls[cr],cr,0),add(rs[cr],cr,0);
    }
    void mdfy(int l,int r,int cr,int L,int R,bool fx)
    {
      if(l>=L&&r<=R)
        {
          if(!fx)add(cr,tot,1);
          else add(tot,cr,0);
          return;
        }
      int mid=l+r>>1;
      if(L<=mid)mdfy(l,mid,ls[cr],L,R,fx);
      if(mid<R)mdfy(mid+1,r,rs[cr],L,R,fx);
    }
    int main()
    {
      n=rdn(); m=rdn(); p=rdn();
      tot=1; build(1,n,1,0);
      rt=++tot; build(1,n,rt,1);
      for(int i=1,a,b,c,d;i<=m;i++)
        {
          a=rdn(); b=rdn(); c=rdn(); d=rdn();
          tot++; mdfy(1,n,1,a,b,0); mdfy(1,n,rt,c,d,1);
          tot++; mdfy(1,n,1,c,d,0); mdfy(1,n,rt,a,b,1);
        }
      memset(dis,0x3f,sizeof dis);
      dis[d1[p]]=0; q.push(make_pair(0,d1[p]));
      while(q.size())
        {
          int k=q.top().second; q.pop();
          if(vis[k])continue; vis[k]=1;
          for(int i=hd[k],v;i;i=nxt[i])
        {
          if(dis[v=to[i]]>dis[k]+w[i])
            dis[v]=dis[k]+w[i],q.push(make_pair(-dis[v],v));
        }
        }
      for(int i=1;i<=n;i++,puts(""))wrt(dis[d1[i]]);
      return 0;
    }
  • 相关阅读:
    《跑跑跑》(五)——添加障碍物,Tiled障碍层的使用
    Cocos2d-JS 自定义loading界面
    Oracle本地,远程,分布式登录
    JUnit测试工具在项目中的用法
    js事件之神奇的onclick
    js常见事件
    JS & DOM 对象
    jquery方法的参数解读
    JDBC和DBUtils区别(查询时jdbc只能返回ResultSet需要po转vo,dbutils返回的BeanListHandler与BeanHandler对应集合与对象)
    AJAX技术的核心
  • 原文地址:https://www.cnblogs.com/Narh/p/9869651.html
Copyright © 2011-2022 走看看