zoukankan      html  css  js  c++  java
  • bzoj2588 Spoj 10628. Count on a tree

    bzoj2588 Spoj 10628. Count on a tree

    题意:

    n点树,m个询问求点u到点v路径上第k小的点权。强制在线。n,m≤100000

    题解:

    用主席树维护某节点到根节点的权值数量sz,建树过程可以由父亲节点递推。询问就用倍增求出lca,然后路径上的sz值就为sz[u]-sz[lca]+sz[v]-sz[fa[lca]]。反思:本弱倍增数组写反了,疯狂reQAQ~

    代码:

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cstring>
     4 #define inc(i,j,k) for(int i=j;i<=k;i++)
     5 #define maxn 100500
     6 using namespace std;
     7 
     8 int f[18][maxn],rt[maxn],dep[maxn],ch[maxn*35][2],sz[maxn*35],v[maxn],id[maxn],n,m,size,last,tot;
     9 struct e{int t,n;}; e es[maxn*2]; int ess,g[maxn];
    10 void pe(int f,int t){es[++ess]=(e){t,g[f]}; g[f]=ess; es[++ess]=(e){f,g[t]}; g[t]=ess;}
    11 struct abc{int v,id;}; abc abcd[maxn]; bool cmp(abc a,abc b){return a.v<b.v;}
    12 inline int read(){
    13     char ch=getchar(); int x=0,f=1;
    14     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    15     return f*x;
    16 }
    17 void build1(int &x,int l,int r){
    18     x=++size; sz[x]=ch[x][0]=ch[x][1]=0; if(l==r)return;
    19     int mid=(l+r)>>1; build1(ch[x][0],l,mid); build1(ch[x][1],mid+1,r);
    20 }
    21 void insert(int &x,int l,int r,int val){
    22     size++; sz[size]=sz[x]+1; ch[size][0]=ch[x][0]; ch[size][1]=ch[x][1]; x=size; if(l==r)return;
    23     int mid=(l+r)>>1; if(val<=mid)insert(ch[x][0],l,mid,val); if(val>mid)insert(ch[x][1],mid+1,r,val);
    24 }
    25 void dfs(int x,int fa){
    26     rt[x]=rt[fa]; insert(rt[x],1,tot,v[x]);
    27     for(int i=g[x];i;i=es[i].n)if(es[i].t!=fa){
    28         f[0][es[i].t]=x; dep[es[i].t]=dep[x]+1; dfs(es[i].t,x);
    29     }
    30 }
    31 void build2(){
    32     for(int i=1;(1<<i)<=n;i++)inc(j,1,n)f[i][j]=f[i-1][f[i-1][j]];
    33 }
    34 int LCA(int u,int v){
    35     if(dep[u]<dep[v])swap(u,v); int t=dep[u]-dep[v];
    36     for(int i=0;(1<<i)<=n;i++)if(t&(1<<i))u=f[i][u];
    37     for(int i=16;i>=0;i--)if(f[i][u]!=f[i][v])u=f[i][u],v=f[i][v];
    38     return u==v?u:f[0][u];
    39 }
    40 int solve(int u,int v,int k){
    41     int lca=LCA(u,v),l=1,r=tot,x1=rt[v],x2=rt[f[0][lca]],x3=rt[u],x4=rt[lca];
    42     while(l<r){
    43         int mid=(l+r)>>1,tmp=sz[ch[x1][0]]-sz[ch[x2][0]]+sz[ch[x3][0]]-sz[ch[x4][0]];
    44         if(tmp>=k)
    45             r=mid,x1=ch[x1][0],x2=ch[x2][0],x3=ch[x3][0],x4=ch[x4][0];
    46         else
    47             k-=tmp,l=mid+1,x1=ch[x1][1],x2=ch[x2][1],x3=ch[x3][1],x4=ch[x4][1];
    48     }
    49     return l;
    50 }
    51 int main(){
    52     n=read(); m=read(); inc(i,1,n)abcd[i]=(abc){read(),i}; inc(i,1,n-1){int a=read(),b=read(); pe(a,b);}
    53     sort(abcd+1,abcd+1+n,cmp);
    54     inc(i,1,n){if(i==1||abcd[i].v!=abcd[i-1].v)++tot,id[tot]=abcd[i].v; v[abcd[i].id]=tot;}
    55     size=0; build1(rt[0],1,tot); dfs(1,0); build2();
    56     inc(i,1,m){
    57         int u=read()^last,v=read(),k=read(); last=id[solve(u,v,k)]; printf("%d",last); if(i!=m)puts("");
    58     }
    59     return 0;
    60 }

    20160621

  • 相关阅读:
    codephp 自研PHP框架并实现composer包管理
    收藏!17 张程序员专属壁纸(使用频率很高)
    git reset hard HEAD^后显示more?的解决方案
    如果有一天我不得不离开IDE,没有其它原因,一定是ta ?
    centos7 下安装composer失败
    不知道如何技术变现?19个程序员接私活平台汇总
    MySQL常见面试题:什么是主从延时?如何降低主从延时?
    Nginx服务器,修改html 文件后页面不更新生效(已解决)
    《Microsoft SQL Server 2005: 数据库基础由入门到精通》书评
    讲座资源:Silverlight In Action
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5701067.html
Copyright © 2011-2022 走看看