Codeforces Round #326 (Div. 1) C. Duff in the Army
来源:互联网 发布:linux查看普通用户 编辑:程序博客网 时间:2024/06/06 05:55
题目描述:
C. Duff in the Army
time limit per test4 seconds
memory limit per test512 megabytes
inputstandard input
outputstandard output
Recently Duff has been a soldier in the army. Malek is her commander.
Their country, Andarz Gu has n cities (numbered from 1 to n) and n - 1 bidirectional roads. Each road connects two different cities. There exist a unique path between any two cities.
There are also m people living in Andarz Gu (numbered from 1 to m). Each person has and ID number. ID number of i - th person is i and he/she lives in city number ci. Note that there may be more than one person in a city, also there may be no people living in the city.
Malek loves to order. That’s why he asks Duff to answer to q queries. In each query, he gives her numbers v, u and a.
To answer a query:
Assume there are x people living in the cities lying on the path from city v to city u. Assume these people’s IDs are p1, p2, …, px in increasing order.
If k = min(x, a), then Duff should tell Malek numbers k, p1, p2, …, pk in this order. In the other words, Malek wants to know a minimums on that path (or less, if there are less than a people).
Duff is very busy at the moment, so she asked you to help her and answer the queries.
Input
The first line of input contains three integers, n, m and q (1 ≤ n, m, q ≤ 105).
The next n - 1 lines contain the roads. Each line contains two integers v and u, endpoints of a road (1 ≤ v, u ≤ n, v ≠ u).
Next line contains m integers c1, c2, …, cm separated by spaces (1 ≤ ci ≤ n for each 1 ≤ i ≤ m).
Next q lines contain the queries. Each of them contains three integers, v, u and a (1 ≤ v, u ≤ n and 1 ≤ a ≤ 10).
Output
For each query, print numbers k, p1, p2, …, pk separated by spaces in one line.
题解:
询问很多次,但是不修改.找出树上一条链的最小的10个数.每个树上结点有若干权值,保证都不一样.
第一反应是树链剖分+区间求最小10的值. 因为log太多,然而我们可以打st表. 方便的是每个权值都不一样,合并的时候相同的算一次就好.
答案的方法更好:类似于求lca的,保存到父亲的2^i的信息,然后每次算一下,只能够搞不修改的,但是不用额外的数据结构
重点:
只能有log * 10, 所以我们要利用好离线的性质
代码:
#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <vector>using namespace std;const int maxn = 1e5 + 100;const int key = 10;struct aut{ int a[12]; aut() { memset(a, 0, sizeof(a)); }};aut st[21][maxn];int n, no[maxn], fanno[maxn], L2[maxn], m, q;int fa[maxn], dep[maxn], top[maxn], siz[maxn], son[maxn], cnt;vector<int> G[maxn];void dfs1(int u, int pa) { siz[u] = 1; for(int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if(v != pa) { dep[v] = dep[u] + 1; fa[v] = u; dfs1(v, u); siz[u] += siz[v]; if(siz[v] > siz[son[u]]) son[u] = v; } }}void dfs2(int u, int tp) { top[u] = tp; ++cnt; no[u] = cnt; fanno[cnt] = u; if(son[u]) { dfs2(son[u], tp); } for(int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if(v != fa[u] && v != son[u]) { dfs2(v, v); } }}aut getMerge(aut x, aut y) { aut ans; // printf("%d %d\n", x.a[0], y.a[0]); int i = 0, j = 0, z = 0; while(x.a[i] != 0 || y.a[j] != 0) { // printf("fasd %d\n", x.a[0]); if(y.a[j] == 0 ||(x.a[i] != 0 && x.a[i] < y.a[j])) { // printf("no\n"); ans.a[z] = x.a[i]; z++; i++; } else if(x.a[i] == 0 || y.a[j] < x.a[i]) { ans.a[z] = y.a[j]; z++; j++; // printf("*****%d\n", ans.a[0]); } else { // printf("kao %d %d\n", x.a[0], i); ans.a[z] = x.a[i]; z++; i++; j++; } if(z >= key) break; } //printf("%d\n", ans.a[0]); return ans;}void getST() { // st 0 already // printf("----- %d %d\n", st[1][4].a[0], st[1][4].a[1]); for(int s = 1; s <= 20; s++) { for(int i = 1; i + (1 << s) - 1 <= n; i++) { int j = i + (1 << (s - 1)); //printf("s %d i %d\n", s, i); st[s][i] = getMerge(st[s - 1][i], st[s - 1][j]); } } // printf("----- %d %d\n", st[1][4].a[0], st[1][4].a[1]);}aut query(int l, int r) { int len = r - l + 1; int s = L2[len]; // printf("---- %d %d %d\n", l, r, s); aut ans; //printf("merge %d %d\n", st[s][l].a[0], st[s][l].a[1]); ans = getMerge(st[s][l], st[s][r - (1 << s) + 1]); //for(int i = 0; ans.a[i] != 0; i++) // printf("zzzzzzz %d ", ans.a[i]); // printf("\n"); return ans;}aut divide(int u, int v) { int ut = top[u], vt = top[v]; aut ans; while(ut != vt) { if(dep[ut] < dep[vt]) { swap(ut, vt); swap(u, v); } ans = getMerge(ans, query(no[ut], no[u])); u = fa[ut]; ut = top[u]; } if(dep[u] < dep[v]) swap(u, v); //printf("** %d %d\n", no[v], no[u]); ans = getMerge(ans, query(no[v], no[u])); return ans;}void solve() { fa[1] = 0; dep[1] = 0; son[0] = 0; siz[0] = 0; dfs1(1, 0); cnt = 0; dfs2(1, 1); for(int i = 1; i <= m; i++) { int t; scanf("%d", &t); aut tmp; tmp.a[0] = i; st[0][no[t]] = getMerge(st[0][no[t]], tmp); } getST(); for(int i = 1;i <= q; i++) { int u, v, a; scanf("%d%d%d", &u, &v, &a); aut ans = divide(u, v); //printf("%d %d %d\n", no[u], no[v], ans.a[0]); int num = 0; for(int j = 0; ans.a[j] != 0 && j < a; j++) { num++; } printf("%d", num); for(int j = 0; j < num; j++) { printf(" %d", ans.a[j]); } printf("\n"); }}int main() { //freopen("D.txt", "r", stdin); L2[0] = -1; for(int i = 1; i <= 100000; i++) { if((i & (i - 1)) == 0) L2[i] = L2[i - 1] + 1; else L2[i] = L2[i - 1]; } while(scanf("%d%d%d", &n, &m, &q) != EOF) { for(int i = 1; i <= n; i++) { G[i].clear(); } for(int i = 1; i <= n - 1; i++) { int u, v; scanf("%d%d", &u, &v); G[u].push_back(v); G[v].push_back(u); } solve(); } return 0;}
- Codeforces Round #326 (Div. 1) C. Duff in the Army
- Codeforces Round #326 (Div. 2) E. Duff in the Army
- Codeforces Round #326 (Div. 2) E. Duff in the Army(LCA+倍增法)
- Codeforces 587C Duff in the Army
- 【Codeforces Round 326 (Div 2)E】【树链剖分】Duff in the Army 树上给定路径上编号最小的几个人
- Codeforces Round #326 Duff in the Army(主席树+LCA)
- CF #326 (Div. 2) E Duff in the Army
- 【LCA】CodeForce #326 Div.2 E:Duff in the Army
- Codeforces Round #326 (Div. 1) B Duff in Beach
- Codeforces Round #326 (Div. 1)-B. Duff in Beach
- Codeforces Round #326 (Div. 2)B. Duff in Love
- Codeforces Round #326 (Div. 2) 588 B. Duff in Love
- Codeforces Round #326 (Div. 2) B. Duff in Love
- Codeforces Round #326 (Div. 2)B. Duff in Love
- Codeforces Round #326 (Div. 2) D. Duff in Beach
- CF587C Duff in the Army
- codeforces587C Duff in the Army
- Codeforces Round #326 (Div. 1)A. Duff and Weight Lifting
- 软件开发概述
- 有向图(3)--寻找有向环
- Java Swing中图标,背景等最好用的类和方法
- cakephp 框架
- High Performance Mysql 读书笔记——创建高性能索引
- Codeforces Round #326 (Div. 1) C. Duff in the Army
- nginx的缓存设置 expires缓存提升网站负载
- 如何利用MVC+EF实现前台传值
- Spring.NET学习笔记2——环境搭建(基础篇) Level 200
- js对象的创建和继承
- ios开发之个人笔记(通过plist文件展示单组数据LOL)
- 组装服务器注意事项
- cakePHP 入门与应用
- 《非同儿戏的数据》