「日常训练」Duff in the Army (Codeforces Round #326 Div.2 E)
题意(CodeForces 588E)
给定一棵\(n\)个点的树,给定\(m\)个人(\(m\le n\))在哪个点上的信息,每个点可以有任意个人;然后给\(q\)个询问,每次问\(u\)到\(v\)上的路径有的点上编号最小的\(k(k \le 10)\)个人(没有那么多人就该有多少人输出多少人)。
分析
\(u\)到\(v\)上路径的询问很显然的想到LCA,但是要维护前\(k\)个在路径上的最小的点似乎是个有点麻烦的问题。其实,找到了LCA(设为\(p\)点),我们就可以同样的利用倍增的思想把\(u\)到\(p\)与\(v\)到\(p\)点的路径上的人全部求出(这里有个小技巧,对于\(u\)和\(v\)点不妨错开一层求,这样可以避免去重的问题)。然后就是前\(k\)大了,这里网上有的题解比较牛逼,起手一个主席树,本数据结构废物并不会,所以学习了一下CF的题解,采用了一种比较简单的方法来处理(注意到\(k\)最大值不超过10)。
代码
经典的倍增在线求LCA板子。
#include <bits/stdc++.h>
#define rep(i,a,b) for(repType i=(a); i<=(b); ++i)
#define per(i,a,b) for(repType i=(a); i>=(b); --i)
#define ZERO(x) memset(x,0,sizeof(x))
#define MS(x,y) memset(x,y,sizeof(x))
#define PB emplace_back
#define MP make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef ll repType;
const int MAXN=100005;
const int MAXD=18;
vector<int> G[MAXN];
struct Node
{
    int a[11];
    Node() { MS(a, 63); }
    void
    insert(int x)
	{
        a[10]=x;
        sort(a, a+11);
    }
} vals[MAXD][MAXN];
Node
merge_node(const Node& x, const Node& y)
{
    Node ans=x;
    rep(i, 0, 10) { ans.insert(y.a[i]); }
    return ans;
}
int fa[MAXD][MAXN], d[MAXN];
void
dfs(int pre, int now)
{
    fa[0][now]=pre;
    rep(i, 1, MAXD-1)
    {
        fa[i][now]=fa[i-1][fa[i-1][now]];
        vals[i][now]=merge_node(vals[i-1][now], vals[i-1][fa[i-1][now]]);
    }
    rep(i, 0, int(G[now].size())-1)
    {
        int v=G[now][i];
        if(v!=pre)
        {
            d[v]=d[now]+1;
            dfs(now, v);
        }
    }
}
inline int
get_fa(int v, int k) // k=1, it will points to v _itself_.
{
    rep(i, 0, MAXD-1)
		if((1<<i) & k)
		    { v=fa[i][v]; }
    return v;
}
int
LCA(int u, int v)
{
    if(d[u]<d[v]) { swap(u, v); }
    u=get_fa(u, d[u]-d[v]);
	if(u==v) { return u; }
    else per(i, MAXD-1, 0)
	{
		if(fa[i][u]!=fa[i][v])
		{
			u=fa[i][u];
			v=fa[i][v];
		}
	}
    return fa[0][v];
}
inline Node
get_people(int v, int k)
{
    Node ans;
    rep(i, 0, MAXD-1)
        if((1<<i) & k)
        {
            ans=merge_node(ans, vals[i][v]);
            v=fa[i][v];
        }
    return ans;
}
int
main()
{
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int n, m, q; cin>>n>>m>>q;
    rep(i, 1, n-1)
    {
        int u, v; cin>>u>>v;
        G[u].PB(v); G[v].PB(u);
    }
    rep(i, 1, m)
    {
        int c; cin>>c;
        vals[0][c].insert(i);
    }
    dfs(1, 1);
    rep(i, 1, q)
    {
        int u, v, k; cin>>u>>v>>k;
        int p=LCA(u, v);
        Node x=get_people(u, d[u]-d[p]); // it will get the point _below_ the LCA.
        Node y=get_people(v, d[v]-d[p]+1); // it will go through another route,
        Node ans=merge_node(x, y);         // if not, y _itself_ must be the LCA,
        int tmp=0;                         // and the y will be the value of V.
        while(tmp<k && ans.a[tmp]<=m) { tmp++; }
        k=tmp;
        cout<<k;
        rep(i, 0, k-1) cout<<" "<<ans.a[i];
        cout<<endl;
    }
    return 0;
}
「日常训练」Duff in the Army (Codeforces Round #326 Div.2 E)的更多相关文章
- 「日常训练」Kefa and Dishes(Codeforces Round #321 Div. 2 D)
		题意与分析(CodeForces 580D) 一个人有\(n\)道菜,然后要点\(m\)道菜,每道菜有一个美味程度:然后给你了很多个关系,表示如果\(x\)刚好在\(y\)前面做的话,他的美味程度就会 ... 
- 「日常训练」Kefa and Park(Codeforces Round #321 Div. 2 C)
		题意与分析(CodeForces 580C) 给你一棵树,然后每个叶子节点会有一家餐馆:你讨厌猫(waht?怎么会有人讨厌猫),就不会走有连续超过m个节点有猫的路.然后问你最多去几家饭店. 这题我写的 ... 
- 「日常训练」Kefa and Company(Codeforces Round #321 Div. 2 B)
		题意与分析(CodeForces 580B) \(n\)个人,告诉你\(n\)个人的工资,每个人还有一个权值.现在从这n个人中选出m个人,使得他们的权值之和最大,但是对于选中的人而言,其他被选中的人的 ... 
- 「日常训练」Case of Matryoshkas(Codeforces Round #310 Div. 2 C)
		题意与分析(CodeForces 556C) 为了将所有\(n\)个娃娃编号递增地串在一起(原先是若干个串,每个串是递增的), 我们有两种操作: 拆出当前串中最大编号的娃娃(且一定是最右边的娃娃). ... 
- 「日常训练」Brackets in Implications(Codeforces Round 306 Div.2 E)
		题意与分析 稍微复杂一些的思维题.反正这场全是思维题,就一道暴力水题(B).题解直接去看官方的,很详尽. 代码 #include <bits/stdc++.h> #define MP ma ... 
- 「日常训练」Divisibility by Eight(Codeforces Round 306 Div.2 C)
		题意与分析 极简单的数论+思维题. 代码 #include <bits/stdc++.h> #define MP make_pair #define PB emplace_back #de ... 
- 「日常训练」Paths and Trees(Codeforces Round 301 Div.2 E)
		题意与分析 题意是这样的,定义一个从某点出发的所有最短路方案中,选择边权和最小的最短路方案,称为最短生成树. 现在求一棵最短生成树,输出总边权和与选取边的编号. 我们首先要明白这样一个结论:对一个图求 ... 
- 「日常训练」Bad Luck Island(Codeforces Round 301 Div.2 D)
		题意与分析(CodeForces 540D) 是一道概率dp题. 不过我没把它当dp做... 我就是凭着概率的直觉写的,还好这题不算难. 这题的重点在于考虑概率:他们喜相逢的概率是多少?考虑超几何分布 ... 
- 「日常训练」Mike and Feet(Codeforces Round #305 Div. 2 D)
		题意 (Codeforces 548D) 对一个有$n$个数的数列,我们要求其连续$x(1\le x\le n)$(对于每个$x$,这样的连续group有若干个)的最小数的最大值. 分析 这是一道用了 ... 
随机推荐
- Centos7 yum安装mysql
			参考此文档:http://www.jb51.net/article/116032.htm http://www.jb51.net/article/95399.htm 1.在官网下载mysql57-co ... 
- 2018 Multi-University Training Contest 3 Problem F. Grab The Tree 【YY+BFS】
			传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6324 Problem F. Grab The Tree Time Limit: 2000/1000 MS ... 
- list,arraylist,哈希表,字典,datatable的selct等等用法
			例子一.获取到list中的最大值,极其索引 List<int> ls = new List<int>(); ls.Add(1); l ... 
- 浅谈DB2在线分析处理函数
			最近碰到一个测试需求,使用到了在线分析处理(OLAP),现总结记录一下,也希望能帮到有相关问题的朋友. 1. 测试环境是DB2,通过ETL(数据抽取,数据转换,数据加载)技术将数据源数据加载到目标数据 ... 
- CSS-自定义变量
			使用背景: 一些常见的例子: 为风格统一而使用颜色变量 一致的组件属性(布局,定位等) 避免代码冗余 *更方便的从CSS向JS传递数据(例如媒体断点) 为什么使用: 以下几点是未来CSS属性的简短说明 ... 
- 【oracle笔记4】存储过程
			存储过程是一组为了完成特定功能的sql语句集,存储在数据库中,经过一次编译后再次调用不需要编译.用户通过指定存储过程的名字来执行它. 基本语法: create or replace procedure ... 
- 【Django笔记二】Django2.0配置模板和静态文件
			一.环境版本信息: 操作系统:windows10 Django版本:2.0.5 Python版本:3.6.4 二.创建模板 1.在my_project文件夹下新建文件夹templates用于存放模板文 ... 
- Mysql 几种常见的插入 Insert into,Replace Into,Insert ignore
			简要说下三者的区别:insert into 最普遍的插入,如果表中存在主键相同的数据,执行会报错. replace into 如果表中存在主键相同的数据则根据主键修改当前主键的数据,反之则插入(存在就 ... 
- Linux 只显示目录或者文件方法
			ls 参数 -a 表示显示所有文件,包含隐藏文件-d 表示显示目录自身的属性,而不是目录中的内容-F 选项会在显示目录条目时,在目录后加一个/ 只显示目录 方法一: find . -type d -m ... 
- 《MySQL必知必会》--使用cmd登陆数据库
			数据库:保存有组织的数据的容器(通常是一个文件或一组文件). 表:某种特定类型数据的结构化清单. 模式:关于数据库和表的布局及特性的信息. 列:表中的一个字段.所有表都是由一个或多个列组成的. 数据类 ... 
