#include <iostream>
#include <istream>
#include <sstream>
#include <vector>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <numeric>
#include <chrono>
#include <ctime>
#include <cmath>
#include <cctype>
#include <string>
#include <cstdio>
#include <iomanip>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <iterator>
using namespace std;
class STTable
{
const int STMAXSIZE = 20;
public:
STTable() {
}
~STTable() {
lg2.clear();
dpmin.clear();
dpmax.clear();
};
void Init(int* input, int cnt)
{
lg2.assign(cnt + 1, -1);
dpmin.assign(cnt, vector<int>(STMAXSIZE, 0));
dpmax.assign(cnt, vector<int>(STMAXSIZE, 0));
for (int i = 1; i <= cnt; i++)
lg2[i] = lg2[i - 1] + (i & (i - 1) ? 0 : 1);
for (int i = 0; i < cnt; i++) {
dpmin[i][0] = dpmax[i][0] = input[i];
}
int len = lg2[cnt];
for (int i = 1; i <= len; i++) {
for (int j = 0; lg2[cnt - j] >= i; j++)
{
dpmin[j][i] = min(dpmin[j][i - 1], dpmin[j + (1 << (i - 1))][i - 1]);
dpmax[j][i] = max(dpmax[j][i - 1], dpmax[j + (1 << (i - 1))][i - 1]);
}
}
}
int GetMin(int l, int r) {
int k = lg2[r - l + 1]; //找到当前区间最大的倍增长度
return min(dpmin[l][k], dpmin[r - (1 << k) + 1][k]);
}
int GetMax(int l, int r) {
int k = lg2[r - l + 1]; //找到当前区间最大的倍增长度
return max(dpmax[l][k], dpmax[r - (1 << k) + 1][k]);
}
private:
vector<int> lg2;
vector<vector<int> > dpmin,dpmax;
};
const int maxn = 1e4 + 7,maxm = 100010;
int n,input[maxn],pos[maxm];
int main()
{
int t;
STTable st;
cin >> t;
while (t--) {
cin >> n;
for (int i = 0; i < n; i++) {
cin >> input[i];
//每个输入都不同 所有每个下标不会出现覆盖的情况
pos[input[i]] = i;
}
st.Init(input, n);
bool ok = false;
for (int i = 0; i < n; i++) {
for (int j = i + 3; j < n; j++) {
int tmin = st.GetMin(i, j);
int tmax = st.GetMax(i, j);
// p q r s p == i s == j
// q > s > p > r
//排列 q > input[j] > input[i] > r
//tmax > input[j] > input[i] > tmin
//i pos[tmax] pos[tmin ] j
//极端情况 tmin = input[i] pos[tmax] 无法排在pos[tmin]前面
if (input[j] > input[i] && pos[tmax] < pos[tmin]) {
ok = true;
break;
}
// q < s < p < r
//排列 q < input[j] < input[i] < r
//tmin < input[j] < input[i] < tmax
// q ==> tmin r ==>tmax
//i pos[tmin] pos[tmax] j
//因为input[j] < input[i] tmax 不会是 input[j]
//tmin 不会是 input[i]
if (input[j] < input[i] && pos[tmin] < pos[tmax] ) {
ok = true;
break;
}
}
if (ok) break;
}
if (ok) cout << "YES" << endl;
else cout << "NO" << endl;
}
return 0;
}
习题8-16(uva-1618)
猜你喜欢
转载自blog.csdn.net/seanbill/article/details/117380382
今日推荐
周排行