Codeforces Round #326 (Div. 1) - C. Duff in the Army 树上倍增算法
题意:一个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 树上倍增算法的更多相关文章
- Codeforces Round #326 Div.1 C.Duff in the Army 树上倍增
题意概述: 给出一棵N个结点的树,然后有M个居民分散在这棵树的结点上(允许某个结点没有居民).现在给出一些询问形如u,v,a,定义k=min(x,a),其中x表示的是u->v路径上的居民数量.将 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- 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 ...
- 【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 ...
- 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 ...
随机推荐
- java异常类的使用
1.异常的概念 什么是异常?程序出错分为两部分,编译时出粗和运行时出错.编译时出错是编译器在编译源码时发生的错误: 运行时出错是在编译通过,在运行时出现的错误.这种情况叫异常. 例如:数组越界,除数为 ...
- oracle-绑定变量学习笔记(未完待续)
--定义变量SQL> var a number; --给绑定变量赋值SQL> exec :a :=123; PL/SQL procedure successfully completed. ...
- CSRF 攻击的应对之道
转载自imb文库 CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,该攻击可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击站点,从而在 ...
- Objective-C总Runtime的那点事儿(一)消息机制【转】
RunTime简称运行时.就是系统在运行的时候的一些机制,其中最主要的是消息机制.对于C语言,函数的调用在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 ).编译完成之后直接顺序执行,无任何 ...
- hdoj 1087 (DP)
代码: #include<iostream> #include<cmath> using namespace std; int a[1005], dp[1005]; ...
- Cocos_Code_Ide学习(一):理解Cocos Lua Project下的frameworks的proj.win32
第一次写,不知道有没有用,有不对的地方,接受大家的批评.勿喷,谢谢. 1.首先,创建工程 ------------------------------------------------------- ...
- javascript--15条规则解析JavaScript对象布局(__proto__、prototype、constructor)
大家都说JavaScript的属性多,记不过来,各种结构复杂不易了解.确实JS是一门入门快提高难的语言,但是也有其他办法可以辅助记忆.下面就来讨论一下JS的一大难点-对象布局,究竟设计JS这门语言的人 ...
- 将listBox中信息显示在dataGridview中,操作datagridview后删除listBox信息和SQL数据库信息 续(浅谈listBox..)
应用场景 对datagridview控件使用了解,以及操作datagridview选中的信息删除,并且有二次确认后才删除用户信息.相应的删除listbox中用户信息,下面一起看看需要哪些准备 ...
- ICE学习第四步-----客户端请求服务器返回数据
这次我们来做一个例子,流程很简单:客户端向服务器发送一条指令,服务端接收到这条指令之后,向客户端发送数据库中查询到的数据,最终显示在DataGridView上. 根据上一篇文章介绍的Slice语法,我 ...
- PHP通过链接获取二进制数据的方法
function urltoblob($url){ $data = @file_get_contents($url); //如果file得不到数据,则给空值 if(!$data){ $data = & ...