zoukankan      html  css  js  c++  java
  • FZU 2237 中位数 主席树 树上k大

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <set>
    #include <stack>
    #include <cstdlib>
    #include <algorithm>
    #include <time.h>
    #include <vector>
    #include <cmath>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int>pii;
    const int N=5e4+5;
    const int S=1e5+1;
    const int INF=0x3f3f3f3f;
    struct Edge{
       int v,w,next;
    }edge[N*2];
    int head[N],tot,root[N],n,q;
    void add(int u,int v,int w){
       edge[tot].v=v;
       edge[tot].w=w;
       edge[tot].next=head[u];
       head[u]=tot++; 
    }
    struct Node{
       int l,r,v;
    }o[N*40];
    int sz;
    void add(int &rt,int l,int r,int x){
       o[++sz]=o[rt];rt=sz;
       ++o[rt].v;
       if(l==r)return;
       int m=(l+r)>>1;
       if(x<=m)add(o[rt].l,l,m,x);
       else add(o[rt].r,m+1,r,x);
    }
    int ask(int x,int y,int z,int l,int r,int k){
        if(l==r)return l;
        int c1=o[o[x].l].v+o[o[y].l].v-2*o[o[z].l].v;
        int m=(l+r)>>1;
        if(c1>=k)ask(o[x].l,o[y].l,o[z].l,l,m,k);
        else ask(o[x].r,o[y].r,o[z].r,m+1,r,k-c1);
    }
    int fa[N][20],d[N];
    void dfs(int u,int f,int w){
       fa[u][0]=f;d[u]=d[f]+1;
       if(u!=1)add(root[u]=root[f],1,S,w);
       for(int i=head[u];~i;i=edge[i].next){
          int v=edge[i].v;
          if(v==f)continue;
          dfs(v,u,edge[i].w);
       }
    }
    int lca(int u,int v){
        if(d[u]<d[v])swap(u,v);
        for(int t=d[u]-d[v],i=0;t;t>>=1,++i)
          if(t&1)u=fa[u][i];
        if(u==v)return u;
        for(int i=16;i>=0;--i){
          if(fa[u][i]!=-1&&fa[u][i]!=fa[v][i])
            u=fa[u][i],v=fa[v][i];
        }
        return fa[u][0];
    }
    int main(){
        while(~scanf("%d%d",&n,&q)){
           tot=sz=0;
           memset(head,-1,sizeof(head));
           for(int i=1;i<n;++i){
              int u,v,w;
              scanf("%d%d%d",&u,&v,&w);
              ++w;
              add(u,v,w),add(v,u,w);
           }
           memset(fa,-1,sizeof(fa));
           dfs(1,0,1);
           for(int j=1;j<=16;++j){
              for(int i=1;i<=n;++i){
                 if(fa[i][j-1]!=-1)fa[i][j]=fa[fa[i][j-1]][j-1];
              }
           }
           while(q--){
              int u,v;
              scanf("%d%d",&u,&v);
              int tp=lca(u,v);
              int k=o[root[u]].v+o[root[v]].v-2*o[root[tp]].v;
              if(k&1)k=k/2+1;
              else k/=2;
              printf("%d
    ",ask(root[u],root[v],root[tp],1,S,k)-1);
           }  
        }
        return 0;
    }
    View Code
  • 相关阅读:
    retofit、ButterKnite
    [iOS笔记]Swift中的Optional类型
    [iOS笔记] 网络通信安全与证书
    [iOS]ReactiveCocoa playground配置
    NAT学习笔记
    [iOS学习笔记]runloop runMode方法调研
    Python 装饰器简单介绍
    cookie实现自动登陆原理
    iOS开发添加Reveal工具
    【iOS Programming: The Big Nerd Ranch Guide】【笔记】2
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5455957.html
Copyright © 2011-2022 走看看