#P15959. [Roi2015 Team]错误报告
[Roi2015 Team]错误报告
题目描述
错误发生时的函数调用栈打印是强大的调试工具。考虑程序中函数之间交互的数学模型,称为调用图。
设程序中有 个函数,编号为 到 。考虑有向边集合 ,其中一条边 表示函数 可以调用函数 。集合 的大小称为调用图的复杂度。
例如,考虑如下伪代码程序:
function f(x)
if x > 0 then
return g(x)
else
return h(x)
function g(x)
return x
function h(x)
if x == 0 then
return 1 / x
else
return h(x + 1) + 1
若函数 分别编号为 ,则调用边集合为
复杂度为 。
错误发生时的调用栈打印如下:先输出发生错误的函数编号 ,然后输出直接调用 的函数编号 ,再输出调用 的函数编号 ,依此类推。
例如,上述程序执行 时,调用过程会到达 并发生除以零错误,调用栈打印为:
3
3
3
3
1
Yura 请求 Lesha 帮忙找程序错误,给他发来了若干次错误后的调用栈打印。遗憾的是,这些调用栈被直接连续写在一个文件中,之间没有任何分隔符。同时 Yura 声称错误只可能发生在不超过两个不同函数中,但他不记得具体是哪两个。
Lesha 明白只靠调用栈不够,还要看程序。但在此之前,他想知道:若 Yura 的说法都正确,则该程序调用图的最小可能复杂度是多少。
请构造一个复杂度最小的调用图,使得给定文件可以看作一个或多个连续拼接的调用栈打印,并且直接发生错误的函数不超过两个。
输入格式
第一行包含两个整数 ,表示程序函数数和文件中的行数。
接下来 行,每行包含一个整数 ,表示文件第 行中的函数编号。
数据范围:
- ;
- 。
输出格式
第一行输出一个整数 ,表示调用图的最小可能复杂度。
接下来 行,每行输出两个整数 ,表示函数 可以调用函数 。
如果有多个最优调用图,输出任意一个。
样例输入
3 7
1
3
3
2
3
2
1
样例输出
1
2 3
样例解释
样例中可以认为错误只发生在函数 和 中,文件由五段调用栈拼接而成:
1
3
3
2
3
2
1
此时只有函数 调用函数 ,复杂度为 。