题目来源于牛客竞赛: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题相关推荐

  1. 2019牛客暑期多校训练营 第三场 I Median

    传送门 链接:https://ac.nowcoder.com/acm/contest/883/I 来源:牛客网 JSB has an integer sequence a1,a2,-,ana_1, a ...

  2. 2019牛客暑期多校训练营(第一场)

    传送门 参考资料: [1]:官方题解(提取码:t050 ) [2]:标程(提取码:rvxr ) [3]:牛客题解汇总 A.Equivalent Prefixes(单调栈) •题意 定义两个数组 u,v ...

  3. 【2019牛客暑期多校训练营(第二场)- E】MAZE(线段树优化dp,dp转矩阵乘法,线段树维护矩阵乘法)

    题干: 链接:https://ac.nowcoder.com/acm/contest/882/E?&headNav=acm 来源:牛客网 Given a maze with N rows an ...

  4. 【2019牛客暑期多校训练营(第二场) - D】Kth Minimum Clique(bfs,tricks)

    题干: 链接:https://ac.nowcoder.com/acm/contest/882/D 来源:牛客网 Given a vertex-weighted graph with N vertice ...

  5. 2019牛客暑期多校训练营(第九场)A——The power of Fibonacci(循环节+中国剩余定理(互质)||广义BM)

    链接:https://ac.nowcoder.com/acm/contest/889/A 来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言5242 ...

  6. 题解 | Coffee Chicken-2019牛客暑期多校训练营第十场B题

    题目来源于牛客竞赛:https://ac.nowcoder.com/acm/contest/discuss 题目描述: 输入描述: 输出描述: 示例1: 题解: 代码: #!/usr/bin/pyth ...

  7. 题解 | Popping Balloons-2019牛客暑期多校训练营第十场F题

    题目来源于牛客竞赛:https://ac.nowcoder.com/acm/contest/discuss 题目描述: 输入描述: 输出描述: 示例1: 示例2: 题解: 代码: #include&l ...

  8. 2019牛客暑期多校训练营(第一场)E-ABBA(dp)

    链接:https://ac.nowcoder.com/acm/contest/881/E 来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 524288K,其他语言1048 ...

  9. 暑假N天乐【比赛篇】 —— 2019牛客暑期多校训练营(第二场)

    最近几天都没写博客,真是没什么时间写了,专题卡着,一周四场比赛,场场爆零,补题都补傻了.第一场还差两题可能今天补掉吧,昨天的杭电也是完全没动,感觉...很烦 第二场牛客断断续续也是补了几天...大概一 ...

  10. 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)

    链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...

最新文章

  1. 文件安全传输服务器,安全传输:从文件加载服务器证书
  2. 笔记-项目管理基础知识-项目组织结构
  3. 数据分析TB级别数据量大了怎么办,不会代码模型训练怎么办?
  4. html 按下和松开事件,利用JQuery实现一个键盘按下与松开触发事件
  5. 消息测试服务器,测试统一消息服务器功能
  6. 大学生学图像处理计算机要求,重点大学计算机教材:数字图像处理
  7. linux连接数问题
  8. 《重构 改善既有代码的设计》笔记
  9. fortran语言能用matlab,fortran语言与matlab
  10. (面试总结)您不清楚的18个非技术面试题---今天教你巧妙回答
  11. LaTex学习教程——插入较复杂的表格(合并、换行以及加标题)
  12. JavaScript模拟轮播图效果
  13. 名帖23 杨沂孙 篆书《淮南子·主术训》
  14. 对12306车票数据的提取
  15. JavaScript localStorage、this、let、const
  16. 目前流行的计算机配置有哪些,2019最流行电脑配置
  17. python将考勤表中同一个人,同一日期的多行出勤时间转换成同一列显示的方法
  18. PKU2069 Super Star 点集最小外接球
  19. 千万级流量的优化策略实战
  20. win10系统,修改注册表,Acrobat DC关联pdf格式

热门文章

  1. Unity MMO游戏架构设计之角色设计一
  2. TCP协议的RST标志位
  3. python编程游戏-9个Python编程小游戏,有趣又好玩,简直太棒了
  4. 常德市六中2021年高考成绩查询,铆足“牛劲”,奋蹄新征程! ——常德市六中2021届高三教师牛年备战新高考...
  5. Centos7安装gos脚本
  6. Laya 微信小游戏登录问题
  7. 内定抽奖小程序_微信抽奖助手怎么中奖 无需作弊照样中奖
  8. android SwipeMenuLayout实现控件侧滑删除
  9. 大学实验室面试总结(机器学习)
  10. 电路板上的插头怎么拔下来_怎么从电路板上拆卸多针脚电子元器件