题解 | Guessing ETT-2019牛客暑期多校训练营第三场C题
题目来源于牛客竞赛:https://ac.nowcoder.com/acm/contest/discuss
题目描述:
ZYB is a smart guy.
One day he learns a new method for representing trees: Euler tour technique (ETT). 、
You can find more details about ETT on this web page:
https://en.wikipedia.org/wiki/Euler_tour_technique
https://blog.nowcoder.net/n/7afe88dc36ef4649b4de941f08abf576
If we use vertices rather than edges in ETT, then any tree with N ertices corresponds to a sequence of length 2N−1, let’s call it the vertex-ETT sequence.
In the beginning, ZYB generates a tree (the root of that tree is always 1) and writes down its vertex-ETT sequence.
However, he spilt ink onto the paper by mistake and some numbers were covered in ink.
Can you help him to restore the sequence?
输入描述:
There are multiple test cases. The first line of the input contains an integer T, indicating the number of test cases.
For each test case, the first line contains a integer N (1≤N≤2.5×105),
while the second line contains an integer sequence a(1≤aiN or ai=-1,which means this number was covered by the ink) of length 2N-1, the vertex-ETT sequence.
it is guaranteed that at least one valid sequence exists.
It’s guaranteed that the sum of N of all test cases will not exceed 500000.
Due to the large size of the input, it’s recommended to use a fast way to read the input.
输出描述:
For each case, print 2N-1space-separated integers, the recovered sequence.
If there are multiple solutions, print any of them.
示例1
输入
2
3
1 2 1 -1 1
3
-1 2 3 -1 1
输出
1 2 1 3 1
1 2 3 2 1
题解:
• 一个想当然的做法是,实时维护一个栈,表示目前所到的点到根路径的所有点。
• 一开始先把k放进去。
• 如果遇到一个非-1的数,很简单:
• 如果在栈的倒数第二个位置,就弹出栈的最后一个数字。
• 否则,将这个数加入栈。
• 遇到一个-1,看起来是优先弹栈,如果不能弹了,就用一个没用过的数字?
• 看一个简单的例子:1 ?3 ??4 ?2 1
• 怎么知道第二格要填1呢?
• 如果不填对不对?好像可以!1 5 3 5 1 4 1 2 1!
• 但是如果是这个例子:1 ?3 4 ?2 ??1
• 就不能直接写5了,只能填4或者2。
• 有些时候需要强制填一个后面出现过的数字。
• 假设当前位置是i,后面那个数的位置是j,那么有判定条件:
• (Sum[j-1]-Sum[i])*2=j-i
• 注意还有一个条件是:I 和 j 的奇偶性要相同。
• 上述式子可以简单地线性维护。
• 这样 -1 的流程也就出来了:
• 如果存在一个>i的j满足上述式子,挑一个最小的j,填上对应数字。
• 否则,看能否退栈,能就退,不能就进。
• 这题细节还是比较繁琐的,建议都去实现以下。
• 如果实现精细,复杂度是 O(N) 的。
代码:
#include<bits/stdc++.h>
#define N 1000005
using namespace std;
int a[N],b[N],num[N],n,tot,Case;
vector<int>e[N],app[N],can;int ch[N],sum[N];
set<pair<int,int> >S[2];
void Color(vector<int>be,int around){static int sum[N];static vector<int>st;st.clear();st.push_back(around);sum[0]=be[0];S[0].clear();S[1].clear();for (int i=1;i<be.size();i++){sum[i]=sum[i-1]+(be[i]>0);if (be[i]>0) S[i&1].insert(make_pair(i-2*sum[i-1],i));}++Case;for (int i=0;i<be.size();i++)if (be[i]>0){if (st.size()>1&&st[st.size()-2]==be[i])st.pop_back();else st.push_back(be[i]);}else {//j>i (Sum_{j-1}-Sum_i)*2=j-i i-2*Sum[i] = j-2*Sum[j-1]int j=be.size();while (true){auto it=S[i&1].lower_bound(make_pair(i-2*sum[i],0));if (it==S[i&1].end()||(*it).first!=i-2*sum[i]) break;if ((*it).second<=i) S[i&1].erase(it);else {j=(*it).second;break;}}if (j<be.size()){a[-be[i]]=be[j];if (ch[be[j]]==Case){while (st.back()!=be[j]) st.pop_back();}else ch[be[j]]=Case,st.push_back(be[j]);}else {if (st.size()>1){a[-be[i]]=st[st.size()-2];st.pop_back();}else{assert(can.size());st.push_back(a[-be[i]]=can.back());can.pop_back();}}}
}
void solve(int l,int r,int around){if (l>r) return;vector<int>be;for (int i=l;i<=r;i++)if (a[i]==-1) be.push_back(-i);else {for (int k=0;k+1<app[a[i]].size();k++)solve(app[a[i]][k]+1,app[a[i]][k+1]-1,a[i]);be.push_back(a[i]);i=app[a[i]].back();}Color(be,around);
}
void euler(int x){b[++tot]=x;for (int i=0;i<e[x].size();i++)euler(e[x][i]),b[++tot]=x;
}
void read(int &x){char ch=getchar();x=0;int f=1;for (;ch<'0';ch=getchar()) if (ch=='-') f=-1;for (;ch>='0';ch=getchar()) x=x*10+ch-'0';x*=f;
}
void Print(int x){static int Q[20];*Q=0;for (;x;x/=10) Q[++*Q]=x%10;for (int i=*Q;i;--i) putchar('0'+Q[i]);
}
int main(){int sumN=0;int T;read(T);while (T--){read(n);sumN+=n;for (int i=1;i<2*n;i++) read(a[i]);a[1]=a[2*n-1]=1;for (int i=1;i<=n;i++) app[i].clear();can.clear();for (int i=1;i<2*n;i++)if (a[i]!=-1) app[a[i]].push_back(i);for (int i=1;i<=n;i++)if (!app[i].size()) can.push_back(i);for (int k=0;k+1<app[1].size();k++)solve(app[1][k]+1,app[1][k+1]-1,1);for (int i=1;i<2*n;i++)Print(a[i]),putchar(i==2*n-1?'\n':' ');}//fprintf(stderr,"%d\n",sumN);
}
更多问题,更详细题解可关注牛客竞赛区,一个刷题、比赛、分享的社区。
传送门:https://ac.nowcoder.com/acm/contest/discuss
题解 | Guessing ETT-2019牛客暑期多校训练营第三场C题相关推荐
- 2019牛客暑期多校训练营 第三场 I Median
传送门 链接:https://ac.nowcoder.com/acm/contest/883/I 来源:牛客网 JSB has an integer sequence a1,a2,-,ana_1, a ...
- 2019牛客暑期多校训练营(第一场)
传送门 参考资料: [1]:官方题解(提取码:t050 ) [2]:标程(提取码:rvxr ) [3]:牛客题解汇总 A.Equivalent Prefixes(单调栈) •题意 定义两个数组 u,v ...
- 【2019牛客暑期多校训练营(第二场)- E】MAZE(线段树优化dp,dp转矩阵乘法,线段树维护矩阵乘法)
题干: 链接:https://ac.nowcoder.com/acm/contest/882/E?&headNav=acm 来源:牛客网 Given a maze with N rows an ...
- 【2019牛客暑期多校训练营(第二场) - D】Kth Minimum Clique(bfs,tricks)
题干: 链接:https://ac.nowcoder.com/acm/contest/882/D 来源:牛客网 Given a vertex-weighted graph with N vertice ...
- 2019牛客暑期多校训练营(第九场)A——The power of Fibonacci(循环节+中国剩余定理(互质)||广义BM)
链接:https://ac.nowcoder.com/acm/contest/889/A 来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言5242 ...
- 题解 | Coffee Chicken-2019牛客暑期多校训练营第十场B题
题目来源于牛客竞赛:https://ac.nowcoder.com/acm/contest/discuss 题目描述: 输入描述: 输出描述: 示例1: 题解: 代码: #!/usr/bin/pyth ...
- 题解 | Popping Balloons-2019牛客暑期多校训练营第十场F题
题目来源于牛客竞赛:https://ac.nowcoder.com/acm/contest/discuss 题目描述: 输入描述: 输出描述: 示例1: 示例2: 题解: 代码: #include&l ...
- 2019牛客暑期多校训练营(第一场)E-ABBA(dp)
链接:https://ac.nowcoder.com/acm/contest/881/E 来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 524288K,其他语言1048 ...
- 暑假N天乐【比赛篇】 —— 2019牛客暑期多校训练营(第二场)
最近几天都没写博客,真是没什么时间写了,专题卡着,一周四场比赛,场场爆零,补题都补傻了.第一场还差两题可能今天补掉吧,昨天的杭电也是完全没动,感觉...很烦 第二场牛客断断续续也是补了几天...大概一 ...
- 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)
链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...
最新文章
- 文件安全传输服务器,安全传输:从文件加载服务器证书
- 笔记-项目管理基础知识-项目组织结构
- 数据分析TB级别数据量大了怎么办,不会代码模型训练怎么办?
- html 按下和松开事件,利用JQuery实现一个键盘按下与松开触发事件
- 消息测试服务器,测试统一消息服务器功能
- 大学生学图像处理计算机要求,重点大学计算机教材:数字图像处理
- linux连接数问题
- 《重构 改善既有代码的设计》笔记
- fortran语言能用matlab,fortran语言与matlab
- (面试总结)您不清楚的18个非技术面试题---今天教你巧妙回答
- LaTex学习教程——插入较复杂的表格(合并、换行以及加标题)
- JavaScript模拟轮播图效果
- 名帖23 杨沂孙 篆书《淮南子·主术训》
- 对12306车票数据的提取
- JavaScript localStorage、this、let、const
- 目前流行的计算机配置有哪些,2019最流行电脑配置
- python将考勤表中同一个人,同一日期的多行出勤时间转换成同一列显示的方法
- PKU2069 Super Star 点集最小外接球
- 千万级流量的优化策略实战
- win10系统,修改注册表,Acrobat DC关联pdf格式
热门文章
- Unity MMO游戏架构设计之角色设计一
- TCP协议的RST标志位
- python编程游戏-9个Python编程小游戏,有趣又好玩,简直太棒了
- 常德市六中2021年高考成绩查询,铆足“牛劲”,奋蹄新征程! ——常德市六中2021届高三教师牛年备战新高考...
- Centos7安装gos脚本
- Laya 微信小游戏登录问题
- 内定抽奖小程序_微信抽奖助手怎么中奖 无需作弊照样中奖
- android SwipeMenuLayout实现控件侧滑删除
- 大学实验室面试总结(机器学习)
- 电路板上的插头怎么拔下来_怎么从电路板上拆卸多针脚电子元器件