Codeforces Round #326 Div.1 C.Duff in the Army 树上倍增
题意概述:
给出一棵N个结点的树,然后有M个居民分散在这棵树的结点上(允许某个结点没有居民)。现在给出一些询问形如u,v,a,定义k=min(x,a),其中x表示的是u->v路径上的居民数量。将所有路径上的居民编号升序排列之后得到序列p1,p2,...,px,要求对于每一组询问,输出k,p1,p2,...,pk。
N,M,Q<=10^5,1<=a<=10.
分析:
实际上这个题是被丢在数据结构作业里面的只是。。。。好像没有这个必要?
分析一波可以发现每个点可能在答案中出现的居民最多只有10个,所以说按照出现的顺序依次把每个点的至多10个居民储存起来,然后倍增的时候用归并排序的思想合并就可以了。时间复杂度O(10nlogn)。
实现过程中注意到一些问题,今后用倍增统计点的信息的时候都用半开半闭就好了,加上对链顶端(x=y时对x,否则x,y一起爬之后对x,y,fa[x][0])的特判就可以做到不重不漏统计(之前都是用来求最值之类的所以没有注意到这个问题)。
所以。。。数据结构是树的意思吗。。。。(感觉听了小火车讲课之后写代码的时候都在各种压长度?)
所以这个时限的4s是输入输出的锅?(实测手写0.5s的事情)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cctype>
using namespace std;
const int maxn=; int N,M,Q;
struct edge{ int to,next; }E[maxn<<];
int first[maxn],np,dep[maxn],fa[maxn][],info[maxn][][],sz[maxn][];
int ans[],tmp[]; void add_edge(int u,int v)
{
E[++np]=(edge){v,first[u]};
first[u]=np;
}
void data_in()
{
scanf("%d%d%d",&N,&M,&Q);
int x,y;
for(int i=;i<N;i++){
scanf("%d%d",&x,&y);
add_edge(x,y);
add_edge(y,x);
}
for(int i=;i<=M;i++){
scanf("%d",&x);
if(sz[x][]<) info[x][][sz[x][]++]=i;
}
}
int merge(int *a,int *b,int l1,int l2,int *c)
{
int l=,i=,j=;
while(i<l1&&j<l2&&l<) c[l++]=a[i]<b[j]?a[i++]:b[j++];
while(i<l1&&l<) c[l++]=a[i++];
while(j<l2&&l<) c[l++]=b[j++];
return l;
}
void DFS(int i,int f,int d)
{
fa[i][]=f,dep[i]=d;
for(int j=;(<<j)<d;j++){
fa[i][j]=fa[fa[i][j-]][j-];
sz[i][j]=merge(info[i][j-],info[fa[i][j-]][j-],sz[i][j-],sz[fa[i][j-]][j-],info[i][j]);
}
for(int p=first[i];p;p=E[p].next){
int j=E[p].to;
if(j==f) continue;
DFS(j,i,d+);
}
}
void cc(int *n,int &l,int x,int i)
{
l=merge(n,info[x][i],l,sz[x][i],tmp);
for(int k=;k<l;k++) n[k]=tmp[k];
}
void LCA(int x,int y,int *n,int &l)
{
if(dep[x]<dep[y]) swap(x,y);
int len=dep[x]-dep[y]; l=;
for(int i=;(<<i)<=len;i++)
if((<<i)&len){ cc(n,l,x,i); x=fa[x][i]; }
if(x==y){ cc(n,l,x,); return; }
for(int i=;i>=;i--) if(fa[x][i]!=fa[y][i]){
cc(n,l,x,i); cc(n,l,y,i);
x=fa[x][i],y=fa[y][i];
}
cc(n,l,x,); cc(n,l,y,);
cc(n,l,fa[x][],);
}
void work()
{
DFS(,,);
int x,y,a,l;
for(int i=;i<=Q;i++){
scanf("%d%d%d",&x,&y,&a);
LCA(x,y,ans,l);
printf("%d ",min(a,l));
for(int j=;j<min(a,l);j++) printf("%d ",ans[j]);
printf("\n");
}
}
int main()
{
data_in();
work();
return ;
96 }
Codeforces Round #326 Div.1 C.Duff in the Army 树上倍增的更多相关文章
- 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个 ...
- 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 ...
随机推荐
- C# sqlhelp
public class SqlHelp { //数据库连接字符串 public static string connectionString = ConfigurationManager.Conne ...
- v-if和v-show的区别以及callback回调函数的体会
今天总结一下最近一周碰到的一些问题 一.v-if和v-show的区别 v-show用的是css属性中的display="block/none",元素被隐藏了但是节点还在页面中,但是 ...
- N个数求和
题目: 本题的要求很简单,就是求N个数字的和.麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式. 输入格式: 输入第一行给出一个正整数N(≤100).随后一行按格式a ...
- hdu_2588_GCD
The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes written (a,b),is the ...
- ABAP术语-Business Connector
Business Connector 原文:http://www.cnblogs.com/qiangsheng/archive/2007/12/27/1016379.html XML-based st ...
- mysql修改登录密码三种方式
一.用SET PASSWORD命令 首先登录MySQL,使用mysql自带的那个客户端连接上mysql. 格式:mysql> set password for 用户名@localhost = ...
- wordpress整站无损搬迁的几种方法 最后一种最完美
网站建设之wordpress整站无损搬迁的几种方法 最后一种最完美 网站搬家,当我们更换php虚拟主机,空间升级或更好空间提供商都会发生,站长们请注意,掌握网站迁移方法,是网站日常维护技术中必须掌握的 ...
- thinkphp发送邮箱(以thinkphp5作为示例)。
第一步:设置我们的邮箱客户端授权码 第二步:下载相应的第三方类库(我这里用的PHPemail) 这是phpemailde 第三方类库的文件下载地址:https://github.com/PHPMail ...
- php实现redis
<?php //实例化Redis对象 $red=new Redis(); //链接redis服务 $red->connect('localhost','6379'); //具体操作 $re ...
- python多线程举例
Python中使用线程有两种方式:函数或者用类来包装线程对象. 1. 函数式:调用thread模块中的start_new_thread()函数来产生新线程.如下例: import time ...