题意:一个n个点的数, m个人住在其中的某些点上, 每个人的标号1-m, 询问u-v 路径上标号前a个人,并输出标号,a < 10。

作法, 利用倍增, ID[j][i] 表示i到i的第2^j个祖先上前10个人, 那么每次询问直接维护就好了,细节好多, 刚开始不知道怎么求ID[j][i]。

这里把2^j分成两部分, 前2^(j-1)和 后2^(j-1)个, 然后递推的维护。

感觉树链剖分也可以做, 不知道会不会TLE, 树链剖分的话 线段树的每个点维护10个值, 每次合并就行了。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + ;
const int maxdep = ;
int par[maxdep][maxn], dep[maxn], n;
vector <int> ID[maxdep][maxn], cit[maxn];
vector <int> G[maxn];
void init() {
for (int i = ; i < maxn; i++) {
G[i].clear();
cit[i].clear();
for (int j = ; j < maxdep; j++) {
ID[j][i].clear();
}
}
memset(par, -, sizeof (par));
}
void update(vector <int> &v1, vector <int> &v2) {
for (int x: v2) {
v1.push_back(x);
}
sort (v1.begin(), v1.end());
v1.erase(unique(v1.begin(), v1.end()), v1.end());
while (v1.size() > ) {
v1.pop_back();
}
}
void dfs(int u, int father) {
par[][u] = father;
dep[u] = dep[father] + ;
for (int i = u; i <= u; i++) {
update(ID[][i], cit[par[][i]]);
update(ID[][i], cit[i]);
for (int j = ; j + < maxdep; j++) {
if (~par[j][i]) {
par[j+][i] = par[j][par[j][i]];
update(ID[j+][i], cit[i]);
update(ID[j+][i], ID[j][i]);
update(ID[j+][i], ID[j][par[j][i]]);
} else {
par[j+][i] = -;
}
}
}
for (int v: G[u]) {
if (v != father) {
dfs(v, u);
}
} }
int lca(int u, int v) {
if (dep[u] > dep[v]) {
swap(u, v);
}
for (int k = ; k < maxdep; k++) {
if ((dep[v] - dep[u]) >> k & ) {
v = par[k][v];
}
}
if (u == v) {
return u;
}
for (int i = maxdep-; i >= ; i--) {
if (par[i][u] != par[i][v]) {
u = par[i][u];
v = par[i][v];
}
}
return par[][u];
}
int anc;
vector <int> solve(int u, int v) {
vector <int> res;
if (u == v) {
update(res, cit[u]);
}
for (int i = maxdep-; i >= ; i--) {
if (~par[i][u] && dep[par[i][u]] >= dep[anc]) {
update(res, ID[i][u]);
u = par[i][u];
}
}
for (int i = maxdep-; i >= ; i--) {
if (~par[i][v] && dep[par[i][v]] >= dep[anc]) {
update(res, ID[i][v]);
v = par[i][v];
}
}
vector<int> emp;
update(res, emp);
return res;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int m, q;
while (~scanf ("%d%d%d", &n, &m, &q)) {
init();
for (int i = ; i < n-; i++) {
int u, v;
scanf ("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
for (int i = ; i < m; i++) {
int c;
scanf ("%d", &c);
if (cit[c].size() < ) {
cit[c].push_back(i+);
ID[][c].push_back(i+);
}
}
dfs(, );
while(q--) {
int u, v, a;
scanf ("%d%d%d", &u, &v, &a);
anc = lca(u, v);
auto res = solve(u, v);
int tot = min((int)res.size(), a);
printf("%d%c", tot, " \n"[!tot]);
for (int i = ; i < min((int)res.size(), a); i++) {
printf("%d%c", res[i], " \n"[i+==min((int)res.size(), a)]);
}
}
}
return ;
}

Codeforces Round #326 (Div. 1) - C. Duff in the Army 树上倍增算法的更多相关文章

  1. Codeforces Round #326 Div.1 C.Duff in the Army 树上倍增

    题意概述: 给出一棵N个结点的树,然后有M个居民分散在这棵树的结点上(允许某个结点没有居民).现在给出一些询问形如u,v,a,定义k=min(x,a),其中x表示的是u->v路径上的居民数量.将 ...

  2. Codeforces Round #326 (Div. 2) D. Duff in Beach dp

    D. Duff in Beach Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/588/probl ...

  3. Codeforces Round #326 (Div. 2) C. Duff and Weight Lifting 水题

    C. Duff and Weight Lifting Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest ...

  4. Codeforces Round #326 (Div. 2) B. Duff in Love 分解质因数

    B. Duff in Love Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/588/proble ...

  5. Codeforces Round #326 (Div. 2) A. Duff and Meat 水题

    A. Duff and Meat Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/588/probl ...

  6. Codeforces Round #326 (Div. 2) B Duff in Love 简单数论 姿势涨

    B. Duff in Love time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  7. Codeforces Round #381 (Div. 2) D. Alyona and a tree 树上二分+前缀和思想

    题目链接: http://codeforces.com/contest/740/problem/D D. Alyona and a tree time limit per test2 secondsm ...

  8. 【LCA】CodeForce #326 Div.2 E:Duff in the Army

    C. Duff in the Army Recently Duff has been a soldier in the army. Malek is her commander. Their coun ...

  9. Codeforces Round #326 (Div. 2) B. Pasha and Phone C. Duff and Weight Lifting

    B. Pasha and PhonePasha has recently bought a new phone jPager and started adding his friends' phone ...

随机推荐

  1. 安装Visual Studio 2010时提示"The location specified for the help content store is invalid or you do not have access to it".

    运行注册表: (运行->输入"regedit").在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Help\v1.0中,删除"Loc ...

  2. 用layer添加UIView的动画

    项目有时会遇到用UIView 添加动画的情况,这里我觉得在layer上添加动画比较好,因为可以详细地设定动画属性,方便理解 下面是一个旋转动画: -(void)roundBtnAction:(id)s ...

  3. 文字排版--字号、颜色(font-size, color)

    可以使用下面代码设置网页中文字的字号为12像素,并把字体颜色设置为#666(灰色): body{font-size:12px;color:#666} 示例: <!DOCTYPE HTML> ...

  4. wpf 自定义RadioButton控件样式

    实现的效果为: 我感觉来自定义RadioButton样式和定义button空间的样式差不多,只是类型不同而已. 接下来分析一下样式代码: <!--自定义单选按钮样式-->        & ...

  5. javascript事件详解1

    事件流讲解来袭,嘎嘎嘎嘎嘎 ---------------------------------------------------------------- 1.事件流:描述的是在页面中接受事件的顺序 ...

  6. [转]mysql自动定时备份数据库的最佳方法-支持windows系统

    网上有很多关于window下Mysql自动备份的方法,可是真的能用的也没有几个,有些说的还非常的复杂,难以操作. 我们都知道mssql本身就自带了计划任务可以用来自动备份,可是mysql咱们要怎么样自 ...

  7. Builder 模式

    Builder 模式和 AbstractFactory 模式在功能上很相似,因为都是用来创建大的复杂的对象,它们的区别是:Builder 模式强调的是一步步创建对象,并通过相同的创建过程可以获得不同的 ...

  8. SGU 124.Broken line

    时间限制:0.25s 空间限制:4M 题意: 给出n条线段和一个点,保证所有线段平行X轴或Y,并且闭合成一个多边形.判断这个点的位置是在多边形上,还是多边形内,还是多边形外. solution: 由于 ...

  9. CentOS 忘记root密码,解决方法

    1.开机后,在倒数5秒结束前,按下任意键 2.在显示centos...的那个界面下,按e键(edit) 3.会出现三行的界面,选择中间 kernel...那行,然后按e键 4.在接着出现的那个界面最后 ...

  10. PHP 用户注册

    注册页面 reg.html 负责收集用户填写的注册信息.教程里只列出关键的代码片段,完整的代码附在本节最后. 注册表单 <fieldset> <legend>用户注册</ ...