给一个家谱,回答给的操作结果。

  1)L 按照字典序排序儿子,输出整个家谱。

  2)b 求出所给name的所有兄弟。

  3)c 求出两个name的LCA

读入数据时,我用一个curfather数组维护固定深度的爸爸,之后就可以方便的将所给的数据形式转换成邻接表建图,同时使用map存储name和id号。Tree结构体数组存储每个人的信息,父亲,儿子(vector存储,方便排序等操作),name,深度。

L操作将每个人的儿子排序,递归打印。

b操作直接找到他父亲,用size函数计算儿子数。

c操作用st表+DFS在线求解。

这道题还有两个坑,根的兄弟要输出1,a和b的lca是a或b时,所求为其lca的父亲。

还有就是递归打印会暴栈,要交C++用黑科技的扩栈语句。

//这个题用了我好久,先学LCA,再纠结怎么处理输入数据,立下不a出来不吃饭的flag,最终a了。。

 #include <algorithm>
#include <iostream>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <map>
#pragma comment(linker,"/STACK:102400000,102400000") using namespace std; const int maxn = ;
int N,M,T,rmq[*maxn]; struct ST
{
int stTable[*maxn][];
int prelog2[*maxn]; void init(int n)
{
prelog2[] = ;stTable[][] = ;
for(int i=;i <= n;i++)
{
prelog2[i] = prelog2[i-];
stTable[i][] = i;
if(( << (prelog2[i]+)) == i) ++prelog2[i];
}
for(int i=n;i > ;i--)
{
for(int j=;(i+(<<j)-) < n;j++)
{
stTable[i][j] = rmq[stTable[i][j-]] < rmq[stTable[i+(<<(j-))][j-]] ? stTable[i][j-] : stTable[i+(<<(j-))][j-];
}
}
} int query(int a,int b)
{
if(a > b) swap(a,b);
int k = prelog2[b-a+];
return rmq[stTable[a][k]] < rmq[stTable[b-(<<k)+][k]] ? stTable[a][k] : stTable[b-(<<k)+][k];
}
}; struct Node
{
int to,next;
}; struct LCA
{
int n;
Node edge[*maxn];
int tol,head[maxn],Dfs[*maxn],P[maxn],cnt;
bool vis[maxn];
ST st; void init(int n)
{
this->n = n;
tol = ;
memset(head,-,sizeof head);
} void add_edge(int a,int b)
{
edge[tol].to = b;
edge[tol].next = head[a];
head[a] = tol++;
edge[tol].to = a;
edge[tol].next = head[b];
head[b] = tol++;
} int query(int a,int b)
{
//printf("%d %d:%d\n",P[a],P[b],st.query(P[a],P[b]));
return Dfs[st.query(P[a],P[b])];
} void dfs(int a,int deepth)
{
vis[a] = true;
++cnt;
Dfs[cnt] = a;
rmq[cnt] = deepth;
P[a] = cnt;
//printf("cnt=%d\n",cnt);
for(int i = head[a];i != -;i = edge[i].next)
{
int v = edge[i].to;
if(vis[v]) continue;
dfs(v,deepth+);
++cnt;
Dfs[cnt] = a;
rmq[cnt] = deepth;
}
} void solve(int root)
{
memset(vis,false,sizeof vis);
cnt = ;
//printf("root=%d\n",root);
dfs(root,);
st.init(*n-);
} }lca; int num = ;
int curfather[maxn];
struct Node_son
{
int deepth;
int fa;
vector<int> son;
string name;
}Tree[maxn]; bool cmpson(const int a,const int b) { return Tree[a].name < Tree[b].name;} void Print_Tree(int root)
{
for(int i=;i<Tree[root].deepth;i++) cout << '.';
cout << Tree[root].name << endl;
if(Tree[root].son.empty()) return;
sort(Tree[root].son.begin(),Tree[root].son.end(),cmpson); for(int i=;i < (int)Tree[root].son.size();i++)
{
Print_Tree(Tree[root].son[i]);
}
} int main()
{
while(cin>>N && N)
{
lca.init(N);
map <string ,int > m;
memset(curfather,,sizeof curfather); for(int i=;i<N;i++)
{
cin>>Tree[i].name;
Tree[i].son.clear();
int lev = ;
for(int t = ;t < (int)Tree[i].name.size();t++)
{
if(Tree[i].name[t] != '.') break;
else lev++;
}
Tree[i].name.erase(Tree[i].name.begin(),Tree[i].name.begin()+lev);
m.insert(pair<string,int>(Tree[i].name,i));
Tree[i].deepth = lev; curfather[lev+] = i;
if(lev == ) continue;
Tree[i].fa = curfather[lev];
Tree[Tree[i].fa].son.push_back(i);
lca.add_edge(Tree[i].fa+,i+);
}
string op;cin >> T;
lca.solve(); while(T--)
{
cin >> op;
if(op[] == 'L') //重构树,字典序
{
Print_Tree();
}
else if(op[] == 'b') //兄弟数
{
string son;
cin >> son;
if(son == Tree[].name) cout << <<endl;
else cout << Tree[ Tree[m[son]].fa ].son.size()<<endl;
}
else if(op[] == 'c') //LCA DFS+ST
{
string son1,son2;
cin >> son1 >> son2;
int lllca = lca.query(m[son1]+,m[son2]+) - ;
if(lllca == m[son1] || lllca == m[son2])
cout << Tree[Tree[lllca].fa].name << endl;
else cout << Tree[ lca.query(m[son1]+,m[son2]+) - ].name<<endl;
}
}
}
}

HDU4409-LCA模拟的更多相关文章

  1. 「模拟赛20180306」回忆树 memory LCA+KMP+AC自动机+树状数组

    题目描述 回忆树是一棵树,树边上有小写字母. 一次回忆是这样的:你想起过往,触及心底--唔,不对,我们要说题目. 这题中我们认为回忆是这样的:给定 \(2\) 个点 \(u,v\) (\(u\) 可能 ...

  2. POJ 1330 Tarjan LCA、ST表(其实可以数组模拟)

    题意:给你一棵树,求两个点的最近公共祖先. 思路:因为只有一组询问,直接数组模拟好了. (写得比较乱) 原题请戳这里 #include <cstdio> #include <bits ...

  3. PAT (Advanced Level) 1140~1143:1140模拟 1141模拟 1142暴力 1143 BST+LCA

    1140 Look-and-say Sequence(20 分) 题意:观察序列D, D1, D111, D113, D11231, D112213111, ...,显然后一个串是对前一个串每一小段连 ...

  4. [NOIP模拟赛]约会date LCA(顺便填坑)

    这道题也算是厉害了,改了整整俩小时最后发现是深信的LCA打错了,悲伤啊!信仰崩塌了! 顺便复习LCA,给出模板 void init(){//p[i][j]表示i节点2^j的祖先 int j; for( ...

  5. JZOJ.5326【NOIP2017模拟8.21】LCA 的统计

    Description

  6. [jzoj5786]【NOIP2008模拟】观察 (dfs序+lca)

    传送门 Description infleaking十分愉快地走在路上, 因为经过10^9^9^9年后, 他得到了一个新技能--观察大法. 刚出来的infleaking就想要挑战自我. 为什么infl ...

  7. [JZOJ 5852] [NOIP2018提高组模拟9.6] 相交 解题报告 (倍增+LCA)

    题目链接: http://172.16.0.132/senior/#main/show/5852 题目: 题目大意: 多组询问,每次询问树上两条链是否相交 题解: 两条链相交并且仅当某一条链的两个端点 ...

  8. 【LNOI2014】【BZOJ3626】NOIp2018模拟(三) LCA

    Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设$dep[i]$表示点i的深度,$lca(i,j)$表示i与j的最近公共祖 ...

  9. 【CSP模拟赛】避难向导(倍增lca&树的直径)

    耐力OIer,一天7篇博客 题目描述 “特大新闻,特大新闻!全国爆发了一种极其可怕的病毒,已经开始在各个城市 中传播开来!全国陷入了巨大的危机!大量居民陷入恐慌,想要逃到其它城市以 避难!经调查显示, ...

  10. 【csp模拟赛6】相遇--LCA

    对于30%的数据:暴力枚举判断 对于60%的数据:还是暴力枚举,把两条路径都走一遍计一下数就行,出现一个点被访问两次即可判定重合 对于100%的数据:找出每条路径中距离根最近的点(lca),判断这个点 ...

随机推荐

  1. identity一些接口

    ASP.NET平台通过HttpContext对象提供一些关于用户的有用信息,该对象由Authorize注解属性使用 的,以检查当前请求的状态,考察用户是否已被认证.HttpContext.User属性 ...

  2. ThinkPad T43续命记

    // Description: 原作于2016年8月25日. Mr. Robot 最近有部叫<黑客军团>(Mr. Robot)的戏比较火.目前第二季已经出到一大半了,深得技术宅和技术宅仰慕 ...

  3. Python 常用 代码片段

    文件名字中含有特殊字符转成空格,因为?‘’等作为文件名是非法的.以下正则表达式进行过滤转换 newname = re.sub("[\s+\.\!\/_,$%^*(+\"\')]+| ...

  4. 过渡与动画 - 缓动效果&基于贝塞尔曲线的调速函数

    难题 给过渡和动画加上缓动效果是一种常见的手法(比如具有回弹效果的过渡过程)是一种流行的表现手法,可以让界面显得更加生动和真实:在现实世界中,物体A点到B点往往也是不完全匀速的 以纯技术的角度来看,回 ...

  5. 基于HTML5 Canvas WebGL制作分离摩托车

    工业方面制作图表,制作模型方面运用到 3d 模型是非常多的,在一个大的环境中,构建无数个相同的或者不同的模型,构建起来对于程序员来说也是一件相当头疼的事情,我们利用 HT 帮大家解决了很大的难题,无数 ...

  6. 基于SimpleChain Beta的跨链交互与持续稳态思考

    1. 区块链扩展性迷局 比特币作为第一个区块链应用与运行到目前为止最被信任的公链,其扩展性问题却持续被作为焦点贯穿着整个链的发展周期.事实上,在2009年1月4日比特币出现的那一天到2010年10月1 ...

  7. [朴智妍][Lullaby]

    歌词来源:http://music.163.com/#/song?id=484056971 作曲 : Bum/Sophiya/김용신 [作曲 : Bum/Sophiya/k/gi-myong-xin] ...

  8. Linux下防御DDOS攻击的操作梳理

    DDOS的全称是Distributed Denial of Service,即"分布式拒绝服务攻击",是指击者利用大量“肉鸡”对攻击目标发动大量的正常或非正常请求.耗尽目标主机资源 ...

  9. ELK基础架构解说-运维笔记

    一.ELK日志分析工具介绍1) Elasticsearch1.1)  Elasticsearch介绍ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索 ...

  10. 《Linux内核设计与实现》读书笔记 18

    第十八章调试 18.1 准备开始 一个bug:大部分bug通常都不是行为可靠而且定义明确的 一个藏匿bug的内核版本:找出bug首先出现的版本 相关内核代码的知识和运气 18.2内核中的bug 可以有 ...