当前位置: 代码迷 >> 综合 >> spoj cot Count on a tree (主席树)
  详细解决方案

spoj cot Count on a tree (主席树)

热度:63   发布时间:2023-12-17 03:27:15.0

题意:

思路:

    我们根据dfs顺序建立主席树。求树上第k大,对于u到v的一条路径,我们用u的树+v的树,很明显lca(u,v)多算了一次,fa[lca(u,v)]多算了两次,所以用u的树+v的树-lca(u,v)的树-fa[lca(u,v)]的树即可

错误及反思:

代码:

#include<bits/stdc++.h>
using namespace std;
#define lson l,m
#define rson m+1,r
const int N  = 100100;
int sum[N*20],ls[N*20],rs[N*20],n,m,val[N],id[N],cnt=0,root[N];
vector<int> son[N],v;
int to[N][25],depth[N];int getid(int x){
   return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}int init(int l,int r){int rt=++cnt;sum[rt]=0,ls[rt]=rt,rs[rt]=rt;int m=(l+r)/2;if(l!=r){ls[rt]=init(lson);rs[rt]=init(rson);}return rt;
}void dfs(int now,int fa,int dep){to[now][0]=fa;depth[now]=dep;for(int i=0;i<son[now].size();i++)if(son[now][i]!=fa)dfs(son[now][i],now,dep+1);
}void initlca(){for(int i=1;i<20;i++)for(int j=0;j<=n;j++)to[j][i]=to[to[j][i-1]][i-1];
}int lca(int a,int b){if(depth[a]>depth[b])swap(a,b);for(int i=19;i>=0;i--)if(depth[to[b][i]]>=depth[a])b=to[b][i];if(a==b) return a;for(int i=19;i>=0;i--){if(to[a][i]!=to[b][i]){a=to[a][i];b=to[b][i];}}return to[a][0];
}int update(int pre,int x,int l, int r){int rt=(++cnt);ls[rt]=ls[pre], rs[rt]=rs[pre], sum[rt]=sum[pre]+1;if(l!=r){int m=(l+r)>>1;if(x<=m) ls[rt]=update(ls[pre], x, lson);else rs[rt]=update(rs[pre], x, rson);}return rt;
}void build(int now,int fa){root[now]=update(root[fa],getid(val[now]),1,v.size());for(int i=0;i<son[now].size();i++)if(son[now][i]!=fa)build(son[now][i],now);
}int query(int u,int v,int lc,int flc,int k,int l,int r){if(l==r) return l;int m=(l+r)/2;int num=sum[ls[u]]+sum[ls[v]]-sum[ls[lc]]-sum[ls[flc]];if(num>=k)return query(ls[u],ls[v],ls[lc],ls[flc],k,lson);return query(rs[u],rs[v],rs[lc],rs[flc],k-num,rson);}int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",&val[i]);v.push_back(val[i]);}v.push_back(0);sort(v.begin(),v.end()),v.erase(unique(v.begin(),v.end()),v.end());for(int i=0,u,v;i<n-1;i++){scanf("%d%d",&u,&v);son[u].push_back(v);son[v].push_back(u);}son[0].push_back(1);son[1].push_back(0);root[0]=init(1,v.size());dfs(0,0,1);initlca();build(1,0);while(m--){int u,vv,k,lc,flc;scanf("%d%d%d",&u,&vv,&k);lc=lca(u,vv);flc=to[lc][0];printf("%d\n",v[query(root[u],root[vv],root[lc],root[flc],k,1,v.size())-1]);}
}
  相关解决方案