zoukankan      html  css  js  c++  java
  • BZOJ3488 : [ONTAK2010]Highways

    对于询问(x,y),恰经过一条非树边且不经过树上两点间路径的路径数为:

    ·若x与y成祖先-孩子关系,假设y是x的祖先,z是y到x方向的第一个节点,则

      ans=起点在x的子树里,且终点不在z的子树里的非树边数

    ·若x与y不成祖先-孩子关系,则

      ans=起点在x的子树里,且终点在y的子树里的非树边数

    由于不经过任何非树边也有一解,所以答案要加1

    求出DFS序后线段树合并即可解决

    #include<cstdio>
    const int N=100010,BUF=10500100;
    int n,m,i,x,y,ans;char Buf[BUF],*buf=Buf;
    int g[N],nxt[N<<1],v[N<<1],ed,d[N],size[N],son[N],top[N],f[N],st[N],en[N],dfn;
    int G[N],NXT[N<<1],V[N<<1],sum[N];
    struct Node{int v;Node*l,*r;}pool[7200010],*cur=pool,*T[N];
    inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;}
    inline void swap(int&x,int&y){int z=x;x=y;y=z;}
    inline void add(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
    inline void ADD(int x,int y){V[++ed]=y;NXT[ed]=G[x];G[x]=ed;}
    void dfs(int x){
      size[x]=1;
      for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x]){
        d[v[i]]=d[f[v[i]]=x]+1;dfs(v[i]);size[x]+=size[v[i]];
        if(size[v[i]]>size[son[x]])son[x]=v[i];
      }
    }
    void dfs2(int x,int y){
      st[x]=++dfn;top[x]=y;
      if(son[x])dfs2(son[x],y);
      for(int i=g[x];i;i=nxt[i])if(v[i]!=son[x]&&v[i]!=f[x])dfs2(v[i],v[i]);
      en[x]=dfn;
    }
    inline int lca2(int x,int y){
      int t;
      while(top[x]!=top[y])t=top[y],y=f[top[y]];
      return x==y?t:son[x];
    }
    Node*merge(Node*x,Node*y,int a,int b){
      if(!x)return y;
      if(!y)return x;
      Node*z=cur++;z->v=x->v+y->v;
      if(a==b)return z;
      int mid=(a+b)>>1;
      return z->l=merge(x->l,y->l,a,mid),z->r=merge(x->r,y->r,mid+1,b),z;
    }
    void ins(Node*&x,int a,int b,int c){
      if(!x)x=cur++;x->v++;
      if(a==b)return;
      int mid=(a+b)>>1;
      if(c<=mid)ins(x->l,a,mid,c);else ins(x->r,mid+1,b,c);
    }
    int ask(Node*x,int a,int b,int c,int d){
      if(!x)return 0;
      if(c<=a&&b<=d)return x->v;
      int mid=(a+b)>>1,t=0;
      if(c<=mid)t=ask(x->l,a,mid,c,d);
      if(d>mid)t+=ask(x->r,mid+1,b,c,d);
      return t;
    }
    void dfs3(int x){
      T[x]=cur++;
      for(int i=G[x];i;i=NXT[i])ins(T[x],1,n,V[i]),sum[x]++;
      for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x])dfs3(v[i]),T[x]=merge(T[x],T[v[i]],1,n),sum[x]+=sum[v[i]];
    }
    int main(){
      fread(Buf,1,BUF,stdin),read(n);
      for(i=1;i<n;i++)read(x),read(y),add(x,y),add(y,x);
      for(dfs(1),dfs2(1,1),ed=0,read(m);m--;ADD(x,st[y]),ADD(y,st[x]))read(x),read(y);
      for(dfs3(1),read(m);m--;printf("%d
    ",ans+1)){
        read(x),read(y);
        if(d[x]<d[y])swap(x,y);
        if(st[y]<=st[x]&&en[x]<=en[y])y=lca2(y,x),ans=sum[x]-ask(T[x],1,n,st[y],en[y]);
        else ans=ask(T[x],1,n,st[y],en[y]);
      }
      return 0;
    }
    

      

  • 相关阅读:
    bs4抓取糗事百科
    数据结构(复习排序算法)——选泡插(选择,冒泡,插入,希尔)
    Hive-ha (十三)
    Hive优化(十一)
    Hive压缩和存储(十二)
    Hive权限管理(十)
    Hive的视图和索引(九)
    Hive动态分区和分桶(八)
    Hive(七)Hive参数操作和运行方式
    Redis 基础
  • 原文地址:https://www.cnblogs.com/clrs97/p/4403134.html
Copyright © 2011-2022 走看看