#include #include #include // 使用标准 OI/ACM 风格的快速 I/O void setup_io() { std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); } // 解决单次测试数据的函数 void solve() { int n; std::cin >> n; // pos 数组用于存储每个数字 1...n 在输入排列 a 中的位置(从 1 开始计数) // 大小为 n+1 是为了方便使用 1-based 索引,即 pos[v] = i std::vector pos(n + 1); for (int i = 1; i <= n; ++i) { int val; std::cin >> val; pos[val] = i; } // 如果 n <= 1,答案就是 n if (n <= 1) { std::cout << n << "\n"; return; } // 至少需要一个栈 int m = 1; // 遍历数字 2 到 n,检查相邻数字 i-1 和 i 是否可以放在同一个栈中 for (int i = 2; i <= n; ++i) { // [核心逻辑] // 为了让一个栈能够依次弹出 s, s+1, ..., t,这些数字在入栈时必须以逆序 t, t-1, ..., s 进入。 // 这意味着在原始排列 a 中,t 必须在 t-1 之前,t-1 必须在 t-2 之前,以此类推。 // 即 pos[t] < pos[t-1] < pos[t-2] < ... < pos[s]。 // // 应用到相邻数字 i-1 和 i,如果它们想在同一个栈中,必须满足 pos[i] < pos[i-1]。 // 如果 pos[i-1] < pos[i],这表示 i-1 在 i 之前出现,它们不能放入同一个栈。 // 这时,i-1 是上一个数字段的末尾,而 i 是一个新的数字段的开始。 // 因此,我们必须启用一个新的栈。 if (pos[i - 1] < pos[i]) { m++; } } std::cout << m << "\n"; } int main() { setup_io(); // 多组测试数据 int t; std::cin >> t; while (t--) { solve(); } return 0; }