COCI2014 stogovi
2015-09-07 16:17
549 查看
题目描述:
Mirko在玩堆栈游戏。开始他有一个空的堆栈,编号为0.在第i步(1<=i<=300000),他会选择一个编号为v的堆栈,做如下操作:1.a v 表示将v号堆栈复制一份,新栈的编号为i,并将元素i压入新栈的栈顶。
2. b v 表示将v号堆栈复制一份,新栈的编号为i,将新栈的栈顶元素弹出。
3.c v w 将v号堆栈复制一份,编号为i,并比较第v号和第w号堆栈中有多少相同的数。
输入:
第一行一个整数n,表示有n步。接下来n步,每步表示一个操作,如上所述。
输出:
对所有的b操作和c操作,输出结果,每行一个。b操作需要输出该栈移除的元素,c操作表示两个堆栈的相同的数的个数。样例输入:
5a 0
a 1
b 2
c 2 3
b 4
样例输出:
21
2
分析:
这是一道比较神的题。用堆栈打掩护,其实是一道LCA的题。在考试的时候虽然隐约感觉这些操作与之前的堆栈有所联系,但没有明确的想出来怎样建图(以前没怎么独立做过LCA的题),乱码了200行,一分没有……下来自己又码了一边,居然一边就A了,可能跟我抄了接近十遍的NOIP2013 day2 truck 有很大的关系吧。“a”操作我们将它翻译为在相关节点连一条父子边,i为输入的x的儿子;“b”操作翻译为将i与输入的x的父亲合并在一起,并输出x的栈顶元素;“c”操作翻译为将i与输入的x1合并,寻找i与输入的x2的最近公共祖先,并输出它的深度。因为题目中给出信息每一次压入堆栈的元素并不相同,所以不用担心在lca(i,x2)后面会有相同的数,就可以直接输出deep[lca(i,x2)]。code:
#include<cstdio> #include<cstring> #include<algorithm> #define MAXN 300000 #define MAXD 20 using namespace std; int fa[MAXN+5][MAXD+5],deep[MAXN+5]; int unit[MAXN+5],top[MAXN+5]; int n,d1,d2; char o[2]; int find(int x){return unit[x]==x?x:unit[x]=find(unit[x]);} void dfs(int u,int f) { int i; fa[u][0]=f; deep[u]=deep[f]+1; for(i=1;i<=MAXD;i++) { if(deep[u]<(1<<i)) break; fa[u][i]=fa[fa[u][i-1]][i-1]; } } int lca(int u,int v) { if(deep[u]<deep[v]) swap(u,v); int i,t=deep[u]-deep[v]; for(i=0;i<=MAXD;i++) if((1<<i)&t) u=fa[u][i]; for(i=MAXD;i>=0;i--) if(fa[u][i]!=fa[v][i]) { u=fa[u][i]; v=fa[v][i]; } if(u==v) return u; return fa[u][0]; } int main() { int i; scanf("%d",&n); memset(fa,-1,sizeof fa); for(i=1;i<=n;i++) unit[i]=i; for(i=1;i<=n;i++) { scanf("%s",o); if(o[0]=='a') { scanf("%d",&d1); d1=find(d1); dfs(i,d1); top[i]=i; } else if(o[0]=='b') { scanf("%d",&d1); d1=find(d1); int f=find(fa[d1][0]); top[i]=top[f]; dfs(i,f); unit[i]=f; printf("%d\n",top[d1]); } else if(o[0]=='c') { scanf("%d%d",&d1,&d2); d1=find(d1),d2=find(d2); top[i]=top[d1]; int f1=find(fa[d1][0]),f2=find(d2); dfs(i,f1); unit[i]=d1; int fi=find(i); printf("%d\n",deep[lca(fi,f2)]); } } }
相关文章推荐
- hdu 1533 Going Home 费用流MCMF模板
- HDU 3966 Aragorn's Story 树链剖分
- git项目添加.gitigore文件
- Algorithms—92.Reverse Linked List II
- 扩展Django:实现自己的manage命令
- Algorithms—45.Jump Game II
- GO环境设置
- GO备忘录
- 1101 Oh, my God!【错排】
- 【最近公共祖先】[COCI]STOGOVI
- Algorithm --> 爬楼梯求最大分数
- [FFmpeg] 去除 logo
- Algorithms—39.Combination Sum
- google.com 还会换IP
- IE和Google浏览器事件传递参数不同
- Algorithm --> 棋盘中求出A到B的最小步数
- Algorithm --> 求N以内的真分数个数
- django给admin增加功能
- 悟空:用Go语言编写的全文搜索引擎
- 类别 category 以及类扩展