题意:一个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. spring集成 log4j + slf4j

    以maven web项目为例, 首先.在pom文件引入相关依赖,如下(spring官网文档有介绍): <dependencies> <!-- spring 相关 --> < ...

  2. angularjs-ngTable select filter

    jsp <td title="'Status'" filter="{status: 'select'}" filter-data="fn.sta ...

  3. Echarts使用随笔(2)-Echarts中mapType and data

    本文出处:http://blog.csdn.net/chenxiaodan_danny/article/details/39081071  series : [                {   ...

  4. 远程推送,集成极光的SDK,证书制造

    由于iOS操作系统限制,我们APP在后台不能做操作,也不能接收任何数据,所以需要用推送来接收消息. APNs服务,苹果官方网址:https://developer.apple.com/library/ ...

  5. $.cookie('name', null) 删除cookie 失效问题

    这几天在做网站的用户登录和退出功能,我使用jquery.cookie.js来操作cookie,但是用$.cookie('name', null) 总是失效, 后来使用$.cookie("na ...

  6. Java反射学习(java reflect)(二)

    ok之前说了Java的反射和反射分析类,那这些东西有神马作用呢,下面就来说应用: 三.运行时使用反射分析对象 简单写一个Employee类,然后利用JAVA反射去取name域,getDeclareFi ...

  7. 从XML文件中获取格式化的文本信息

    在FMW的运维过程中,时常需要将中间传输的XML信息转换为excel格式化的问题提交给关联系统人员,现总结三种格式化问题提供方式 一.使用Excel转换 因为从系统中取到的xml文档为中间信息文档,需 ...

  8. css3基础教程十六变形与动画animation

    前面我们讲过的变形与动画一般都是通过鼠标的单击.获得焦点,被点击或对元素进行一定改变后以后触发效果的,那么有没有像Flash一样自动播放的动画效果呢?答案当然是肯定的,这就是我们今天要讲到的anima ...

  9. php如何计算两个时间戳之间相差的日时分秒

    /功能:计算两个时间戳之间相差的日时分秒//$begin_time 开始时间戳//$end_time 结束时间戳function timediff($begin_time,$end_time){ if ...

  10. PHP 用户注册

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