SPOJ 10628 Count on The tree .. .. 主席树
2014-07-30 14:17
465 查看
先离散化出 cnt个不同的数,再以这cnt个不同的数来建立主席树,主席树记录的是某节点的数量,
这样就可以通过树的加减操作,来判断< a[num] 的数有多少个了。。
这题只用从根序列开始,记录到每个点的线段树
DFS从根开始构造序列
可以知道 dist[a,b] = dist[a,root] + dist[b,root] - dist[ lca,root] - dist[fa[lca] , root];
这就是Query的内容了。
ORZ
这样就可以通过树的加减操作,来判断< a[num] 的数有多少个了。。
这题只用从根序列开始,记录到每个点的线段树
DFS从根开始构造序列
可以知道 dist[a,b] = dist[a,root] + dist[b,root] - dist[ lca,root] - dist[fa[lca] , root];
这就是Query的内容了。
ORZ
//tpl //ipqhjjybj_tpl.h //header.h #include <cstdio> #include <cstdlib> #include <map> #include <set> #include <algorithm> #include <cstring> #include <iostream> #include <vector> #include <string> #include <queue> #define mp(x,y) make_pair(x,y) #define pii pair<int,int> #define pLL pair<long long ,long long> #define rep(i,j,k) for(int i = j; i < k;i++) #define nrep(i,j,k) for(int i = j; i <= k;i++) using namespace std; const int N = 111111; const int INF = 0x3f3f3f3f; const int maxs = 20; int a ,b ,fa ,root ,ls[N*20],rs[N*20],deep ; int sum[N*20]; int flca [20]; vector<int> g ; int tot; void build(int l,int r,int &rt){ rt = tot++; sum[rt] = 0; if(l>=r)return; int mid = (l+r)>>1; build(l,mid,ls[rt]); build(mid+1,r,rs[rt]); } void update(int last,int p,int l,int r,int &rt){ rt = tot++; ls[rt] = ls[last], rs[rt] = rs[last]; sum[rt] = sum[last]+1; if(l>=r) return; int mid = (l+r)>>1; if(p <= mid){ update(ls[last],p,l,mid,ls[rt]); }else{ update(rs[last],p,mid+1,r,rs[rt]); } } int query(int left_rt,int right_rt,int lca,int flc,int l,int r,int k){ if(l>=r) return l; int mid = (l+r)>>1; int cnt = sum[ls[left_rt]] + sum[ls[right_rt]] - sum[ls[lca]] - sum[ls[flc]]; if(k <= cnt) return query(ls[left_rt],ls[right_rt],ls[lca],ls[flc],l,mid,k); else return query(rs[left_rt],rs[right_rt],rs[lca],rs[flc],mid+1,r,k-cnt); } int getlca(int u,int v){ if(deep[u] > deep[v]) swap(u,v); if(deep[u] < deep[v]){ int del = deep[v] - deep[u]; for(int i = 0;i < maxs;i++) if(del & (1<<i)) v = flca[v][i]; } if(u!=v){ for(int i = maxs-1; i >= 0;i--) if(flca[u][i] != flca[v][i]) u = flca[u][i], v = flca[v][i]; u = flca[u][0]; } return u; } void dfs(int u,int f,int n){ flca[u][0] = fa[u] = f , deep[u] = deep[f] + 1; for(int i = 1;i < maxs;i++) { flca[u][i] = flca[flca[u][i-1]][i-1]; //printf("flca[%d][%d]=%d\n",u,i,flca[u][i]); } update(root[f],a[u],1,n,root[u]); for(int i = 0;i < g[u].size();i++){ int v = g[u][i]; if(v != f) dfs(v,u,n); } } int main(){ int n,m; int u,v,w; while(scanf("%d %d",&n,&m)!=EOF){ nrep(i,1,n) g[i].clear(); nrep(i,1,n) scanf("%d",a+i); memcpy(b,a,sizeof(a)); sort(b+1,b+1+n); int cnt = unique(b+1,b+1+n) - b-1; nrep(i,1,n){ a[i] = lower_bound(b+1,b+cnt+1,a[i])-b; //printf("a[%d]=%d\n",i,a[i]); } rep(i,1,n){ scanf("%d %d",&u,&v); g[u].push_back(v) , g[v].push_back(u); } tot = 0; build(1,cnt,root[0]); deep[0] = 0; dfs(1,0,cnt); nrep(zz,1,m){ scanf("%d %d %d",&u,&v,&w); int lca = getlca(u,v); int ans = query(root[u],root[v],root[lca],root[fa[lca]],1,cnt,w); printf("%d\n",b[ans]); } } return 0; }
相关文章推荐
- BZOJ 2588: Spoj 10628. Count on a tree|主席树
- 【SPOJ】10628. Count on a tree(lca+主席树+dfs序)
- bzoj2588: Spoj 10628. Count on a tree 主席树+dfs序
- 【BZOJ 2588】 Spoj 10628. Count on a tree|树上K大|树链剖分|主席树
- [BZOJ]2588: Spoj 10628. Count on a tree 主席树+LCA
- SPOJ 10628 Count on a tree (lca+主席树)
- SPOJ_10628_Count_on_a_Tree_(主席树+Tarjan)
- 【bzoj2588】Spoj 10628. Count on a tree LCA+主席树
- 【主席树】bzoj2588 Spoj 10628. Count on a tree
- [bzoj1588]Spoj 10628. Count on a tree 主席树
- BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca
- [主席树] BZOJ 2588 Spoj 10628. Count on a tree
- 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA
- BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )
- SPOJ 10628. Count on a tree (树上第k大,LCA+主席树)
- BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]
- SPOJ 10628 Count on a tree (lca+主席树)
- bzoj 2588 Spoj 10628. Count on a tree(主席树)
- bzoj 2588: Spoj 10628. Count on a tree(树上主席树)
- [主席树] BZOJ2588: Spoj 10628. Count on a tree