Codeforces 587C Duff in the Army
来源:互联网 发布:arnold mac 破解方法 编辑:程序博客网 时间:2024/05/12 16:10
题意:给出一棵树,每个节点有一个权值集合(一个点有多个值),现在有q个询问,query(u,v,a)表示询问u到v之间的前a小的数。
与 http://blog.csdn.net/mr_xujh/article/details/47271843 差不多
就是这一题的每个节点上有多个值,不用离散化,查询的时候要输出前a小
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <vector>#include <algorithm>using namespace std;const int N = 200010;const int M = N * 40;int n,m,q,tot;int a[N],t[N];int T[N],ls[M],rs[M],c[M],d[N],fa[N][27];vector<int> vec[N],peo[N],ans;void init(){ memset(fa, -1, sizeof(fa)); tot = 0;}void build(int l, int r, int &rt){rt = tot ++;c[rt] = 0;if(l != r){int mid = (l+r)>>1;build(l, mid, ls[rt] );build(mid+1, r, rs[rt]);}}int update(int root, int pos, int val){int newroot = tot++, tmp = newroot;c[newroot] = c[root] + val;int l = 1, r = m;while(l < r){int mid = (l+r)>>1;if(pos <= mid){ls[newroot] = tot++;rs[newroot] = rs[root];newroot = ls[newroot];root = ls[root];r = mid;}else {rs[newroot] = tot++;ls[newroot] = ls[root];newroot = rs[newroot];root = rs[root];l = mid+1;}c[newroot] = c[root] + val;}return tmp;}int query(int lrt, int rrt, int lca, int k){int lcart = T[lca], fart = T[fa[lca][0]];int l = 1, r = m;int cot = c[lrt] + c[rrt] - c[lcart] - c[fart];if(cot<k)return -1;while(l < r){int mid = (l+r)>>1;cot = c[ls[lrt]] + c[ls[rrt]] - c[ls[lcart]] - c[ls[fart]];if(cot >= k){r = mid;lrt = ls[lrt];rrt = ls[rrt];lcart = ls[lcart];fart = ls[fart];}else {l = mid+1;k -= cot;lrt = rs[lrt];rrt = rs[rrt];lcart = rs[lcart];fart = rs[fart];}}return l;}void dfs_build(int u, int pre){fa[u][0] = pre;d[u] = d[pre] + 1;int sz = peo[u].size();T[u] = T[pre];for(int i = 0; i < sz; i++){ T[u] = update(T[u], peo[u][i], 1);}//cout<<"ok"<<endl; sz = vec[u].size(); for(int i = 0; i < sz; i++){ int v = vec[u][i]; if(v != pre){ dfs_build(v, u); } }}void init_fa(){ for(int j = 1; (1<<j) <= n; j++){ for(int i = 1; i <= n; i++){ fa[i][j] = fa[fa[i][j-1]][j-1]; } }}int LCA(int a, int b){ int i, j; if(d[a] < d[b])swap(a, b); for(i = 0; (1<<i) <= d[a]; i++);i--; for( j = i; j >= 0; j--){ if(d[a] - (1<<j) >= d[b]) a = fa[a][j]; } if(a == b)return a; for(j = i; j >= 0; j--){ if(fa[a][j] != -1 && fa[a][j] != fa[b][j]){ a = fa[a][j], b = fa[b][j]; } } return fa[a][0];}int main(){int u,v,k; //freopen("in.txt","r",stdin);while(~scanf("%d%d%d", &n, &m, &q)){init();for(int i = 1; i < n; i++){scanf("%d%d", &u, &v);vec[u].push_back(v);vec[v].push_back(u);}for(int i = 1; i <= m ; i++ ){ scanf("%d", &u); peo[u].push_back(i); }build(1, m, T[0]);dfs_build(1, 0);init_fa();while(q--){ ans.clear();scanf("%d%d%d", &u, &v, &k);int lca = LCA(u, v);//cout<<lca<<endl;for(int i = 1; i <= k; i++){ int tmp = query(T[u],T[v],lca,i); if(tmp>0)ans.push_back(tmp); else break;}int sz = ans.size(); printf("%d", sz); for(int j = 0; j < sz; j++) printf(" %d", ans[j]); puts("");}for(int i = 1; i <= n; i++){vec[i].clear(),peo[i].clear();}}return 0;}
0 0
- Codeforces 587C Duff in the Army
- Codeforces Round #326 (Div. 1) C. Duff in the Army
- Codeforces Round #326 (Div. 2) E. Duff in the Army
- CF587C Duff in the Army
- codeforces587C Duff in the Army
- Codeforces Round #326 Duff in the Army(主席树+LCA)
- Codeforces Round #326 (Div. 2) E. Duff in the Army(LCA+倍增法)
- Codeforces 588E Duff in the Army 【树链剖分维护区间前k小】
- Duff in the Army codeforces 588E 树上主席树+lca
- CF #326 (Div. 2) E Duff in the Army
- 【LCA】CodeForce #326 Div.2 E:Duff in the Army
- 【Codeforces Round 326 (Div 2)E】【树链剖分】Duff in the Army 树上给定路径上编号最小的几个人
- Codeforces 587B Duff in Beach
- codeforces 587 B. Duff in Beach
- codeforces 587B Duff in Beach (dp)
- In the army now
- In the Army Now
- Ural1090-In the Army Now
- Java使用POI操作Excel
- QT子线程与主线程的信号槽通信
- Xcode7 真机调试,xcode7真机调试....
- android之短信验证
- 个人博客开启
- Codeforces 587C Duff in the Army
- GeForce > 硬件 > 技术 > VXGI
- maven 配置linux 环境变量
- 从内存溢出看Java 环境中的内存结构
- MVC ajax 给控制器传值接收到为空
- Oracle 用户、对象权限、系统权限
- Spark内核-笔记1
- Linux中禁用nouveau kernel driver后,导致系统无法进入的解决方案 在安装cuda的时候,由于涉及到NVIDIA驱动的安装,使得nouveau驱动与NVIDIA驱动冲突,为了能够
- 【Linux】linux环境下java环境搭建步骤