题目意思:
给定一个数列,找到任意三个数字 a[i],a[j],a[k],i<j<k && a[k]>a[i]>a[j]
首先逆序预处理出每个数字并且包括这个数字右边最大的值。
然后从左到右扫一遍,结合set进行二分查找出刚刚 比当前数字大的数,然后判断是否满足条件。
#include <iostream>
#include <malloc.h>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <sstream>
#include <cstring>
#define IO \
ios::sync_with_stdio(false); \
// cin.tie(0); \
// cout.tie(0);
using namespace std;
typedef long long LL;
const int maxn = 1e6 + 10;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const double PI = 3.14159;
const double eps = 1e-8;
const int mod = 1e9 + 7;
int a[maxn];
int max_a[maxn];
int maxv;
vector<int> ans;
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
IO;
int T, n;
cin >> T;
int kase = 0;
while (T--)
{
++kase;
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
maxv = -1;
for (int i = n; i >= 1; i--) // 逆序处理
{
if (a[i] > maxv)
{
maxv = a[i];
max_a[i] = maxv;
}
else
max_a[i] = maxv;
}
set<int> s;
for (int j = 1; j <= n; j++)
{
if (!s.size() || a[j] == max_a[j])
{
s.insert(a[j]);
continue;
}
set<int>::iterator it = s.upper_bound(a[j]);
// 二分查
if (it != s.end())
{
if (*it < max_a[j])
{
ans.push_back(kase);
break;
}
}
s.insert(a[j]);
}
}
cout << ans.size() << endl;
for (int i = 0; i < ans.size(); i++)
cout << ans[i] << endl;
return 0;
}