zoukankan      html  css  js  c++  java
  • nowcoder172C 保护 (倍增lca+dfs序+主席树)

    https://www.nowcoder.com/acm/contest/172/C

    (sbw大佬太强啦 orz)

    先把每一个路径(x,y)分成(x,lca),(y,lca)两个路径,然后就能发现,对于某两个(直上直下的)路径a,b,b的下端点在a的下端点子树中,且b的上端点深度<=a的上端点深度,那么b是覆盖a的。

    这样的话,我们做一个dfs序,那么能覆盖某个路径的个数就是(下端点在dfs序对应的那个区间中的、上端点深度小于要覆盖的那个路径)的路径的个数。

    而且比较容易发现,我们要求的其实就是dfs序那个区间里的深度第k小的路径。

    这样的话,就可以搞一个主席树,以深度为权值,每条路径下端点的dfs序为时间往里加值,每次只要询问对应区间的第k小就可以。

    不过要注意的是,我找出来的那个点深度大于我在做的这个点的深度的话,是不合法的,要判掉。

      1 #include<bits/stdc++.h>
      2 #define pa pair<int,int>
      3 #define ll long long
      4 using namespace std;
      5 const int maxn=200020,logn=22;
      6 
      7 ll rd(){
      8     ll x=0;char c=getchar();int neg=1;
      9     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
     10     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
     11     return x*neg;
     12 }
     13 
     14 int N,M,L,Q;
     15 int lg[maxn],dep[maxn],fa[maxn][logn];
     16 int egh[maxn],eg[maxn*2][2],ect;
     17 int pth[maxn],pt[maxn*2][2],pct;
     18 int id[maxn],dfn[maxn][2],tot,lst[maxn];
     19 int ch[maxn*logn*8][2],sum[maxn*logn*8],root[maxn*2],rct;
     20 
     21 inline void adeg(int a,int b){
     22     eg[++ect][0]=b;eg[ect][1]=egh[a];egh[a]=ect;
     23 }
     24 inline void adpt(int a,int d){
     25     pt[++pct][0]=d;pt[pct][1]=pth[a];pth[a]=pct;
     26 }
     27 
     28 void dfs(int x){
     29     dfn[x][0]=++tot;id[tot]=x;
     30     for(int i=1;fa[x][i-1]&&fa[fa[x][i-1]][i-1];i++){
     31         fa[x][i]=fa[fa[x][i-1]][i-1];
     32     }
     33     for(int i=egh[x];i!=-1;i=eg[i][1]){
     34         if(dfn[eg[i][0]][0]) continue;
     35         dep[eg[i][0]]=dep[x]+1;fa[eg[i][0]][0]=x;
     36         L=max(L,dep[x]+1);dfs(eg[i][0]);
     37     }dfn[x][1]=tot;
     38 }
     39 
     40 inline int lca(int x,int y){
     41     if(dep[x]<dep[y]) swap(x,y);
     42     while(dep[x]>dep[y]){
     43         x=fa[x][lg[dep[x]-dep[y]]];
     44     }if(x==y) return x;
     45     for(int i=lg[dep[x]-1];i>=0;i--){
     46         if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
     47     }return fa[x][0];
     48 }
     49 
     50 void add(int &rn,int ro,int l,int r,int x){
     51     rn=++rct;sum[rn]=sum[ro]+1;
     52     if(l<r){int m=l+r>>1;
     53         if(x<=m){
     54             add(ch[rn][0],ch[ro][0],l,m,x);ch[rn][1]=ch[ro][1];
     55         }else{
     56             add(ch[rn][1],ch[ro][1],m+1,r,x);ch[rn][0]=ch[ro][0];
     57         }
     58     }
     59 }
     60 int query(int rn,int ro,int l,int r,int k){
     61     //printf("%d %d %d %d %d %d
    ",l,r,rn,ro,sum[rn],sum[ro]);
     62     if(k>sum[rn]-sum[ro]) return -1;
     63     if(l==r) return l;
     64     else{
     65         int m=l+r>>1,w=sum[ch[rn][0]]-sum[ch[ro][0]];
     66         if(w>=k) return query(ch[rn][0],ch[ro][0],l,m,k);
     67         else return query(ch[rn][1],ch[ro][1],m+1,r,k-w);
     68     }
     69 }
     70 
     71 inline int solve(int x,int k){
     72     if(!k) return dep[x]-1;
     73     int y=query(root[lst[dfn[x][1]]],root[lst[dfn[x][0]-1]],1,L,k);
     74     if(y==-1||dep[x]<y) return 0;
     75     else return dep[x]-y;
     76 }
     77 
     78 int main(){
     79     //freopen("protect.in","r",stdin);
     80     int i,j,k;
     81     N=rd(),M=rd();memset(egh,-1,sizeof(egh));
     82     for(i=1,j=0,k=2;i<=N+10;i++){
     83         if(i>=k) j++,k<<=1;lg[i]=j;
     84     }
     85     for(i=1;i<N;i++){
     86         int a=rd(),b=rd();
     87         adeg(a,b);adeg(b,a);
     88     }dep[1]=1;dfs(1);memset(pth,-1,sizeof(pth));
     89     for(i=1;i<=M;i++){
     90         int a=rd(),b=rd();
     91         int x=lca(a,b);
     92         adpt(a,dep[x]);adpt(b,dep[x]);
     93     }
     94     for(i=1,k=0;i<=N;i++){
     95         for(j=pth[id[i]];j!=-1;j=pt[j][1]){
     96             ++k;add(root[k],root[k-1],1,L,pt[j][0]);
     97         }lst[i]=k;
     98     }
     99     Q=rd();
    100     for(i=1;i<=Q;i++){
    101         int a=rd(),b=rd();
    102         printf("%d
    ",solve(a,b));
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    微软消息队列
    使用Memcached Provider客户端的increment()||decrement()操作小结
    SQL While And Sql Array
    好管理是成功的99%
    Javascript图片无缝滚动
    javascript数组复习
    前端面试题--js切换td中的值
    推荐使用:易企在线客服升级版
    drupal中根据不同的内容类型节点显示不同的样式
    defer和async(原生js学习)转
  • 原文地址:https://www.cnblogs.com/Ressed/p/9628631.html
Copyright © 2011-2022 走看看