# D. Permutation Graph
link : https://codeforces.com/problemset/problem/1696/D
tóm tắt đề : cho 1 hoán vị n số, nếu min và max [i...j] nằm ở 2 đầu mút thì có cạnh (i, j) với trọng số 1, tìm minpath 1 -> n.
+ suy nghĩ 1 : khả năng cao là bfs, tìm cách xét mỗi cạnh đúng 1 lần
+ suy nghĩ 2 : dùng kĩ thuật tịnh tiến deque + segment là có thể thực hiện ý tưởng
sml, do code dài quá phải xem hint, dcm non thế này thì chỉ nên làm dev quèn sống qua ngày =))))
:::spoiler
```cpp=
#include<bits/stdc++.h>
#define pii pair<int, int>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define rev(i, a, b) for (int i = (a); i >= (b); --i)
#define X first
#define Y second
using namespace std;
const int mxn = 5e5 + 5;
int a[mxn];
int mi[20][mxn], mx[20][mxn];
int gmi(int l, int r)
{
int x = log2(r - l + 1);
if (a[mi[x][l]] < a[mi[x][r - (1 << x) + 1]]) return mi[x][l];
return mi[x][r - (1 << x) + 1];
}
int gmx(int l, int r)
{
int x = log2(r - l + 1);
if (a[mx[x][l]] > a[mx[x][r - (1 << x) + 1]]) return mx[x][l];
return mx[x][r - (1 << x) + 1];
}
int solve (int l, int r)
{
int a = gmi(l, r), b = gmx(l, r);
if (a == l && b == r) return 1;
if (b == l && a == r) return 1;
int x;
if (a == l || a == r)
x = b;
else x = a;
return (solve(l, x) + solve(x, r));
}
int main() {
//freopen("D:\\test.txt", "r", stdin);
//freopen("D:\\test2.txt", "w", stdout);
int t; cin >> t;
while(t--)
{
int n; cin >> n;
rep(i, 1, n) cin >> a[i];
rep(i, 1, n) mx[0][i] = mi[0][i] = i;
rep(i, 1, 18) rep(u, 1, n)
{
if (a[mx[i - 1][u]] > a[mx[i - 1][u + (1 << (i - 1))]])
mx[i][u] = mx[i - 1][u];
else mx[i][u] = mx[i - 1][u + (1 << (i - 1))];
if (a[mi[i - 1][u]] < a[mi[i - 1][u + (1 << (i - 1))]])
mi[i][u] = mi[i - 1][u];
else mi[i][u] = mi[i - 1][u + (1 << (i - 1))];
}
if (n == 1) cout << "0\n";
else cout << solve(1, n) << "\n";
}
}
```
:::