题目链接
这一题看完的唯一想法就是RMQ其他别无想法,但是仔细一想,如果是1到n中只放一个点然后来查找的话,然后要查找是否存在一个点为分界线使得左边的最小值等于右边的嘴大值时是满足单调性的,因为越往右移动最小值也越小,最大值也越小所以是满足单调性的,这里是中间有两个点,所以我们可以固定左边界,然后二分再查找是否有满足题意的点。不过二分的边界情况有点难搞,仔细理一下就好了。
//#include<bits/stdc++.h>
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<algorithm>
#include<deque>
#include<map>
#include<stdlib.h>
#include<set>
#include<iomanip>
#include<stack>
#define ll long long
#define ms(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x & -x
#define fi first
#define ull unsigned long long
#define se second
#define lson (rt<<1)
#define rson (rt<<1|1)
#define endl "\n"
#define bug cout<<"----acac----"<<endl
#define IOS ios::sync_with_stdio(false), cin.tie(0),cout.tie(0)
using namespace std;
const int maxn = 4e5 + 10;
const int maxm = 1e4 + 50;
const double eps = 1e-7;
const ll inf = 0x3f3f3f3f;
const ll lnf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
int q[maxn], n, dpmax[maxn][33], dpmin[maxn][33];
void rmq()
{
for (int i = 1; i <= n; i++)
{
dpmax[i][0] = q[i];
dpmin[i][0] = q[i];
}
for (int j = 1; (1 << j) <= n; j++)
{
for (int i = 1; i + (1 << j) - 1 <= n; i++)//修改了i=0
{
dpmax[i][j] = max(dpmax[i][j - 1], dpmax[i + (1 << (j - 1))][j - 1]);
dpmin[i][j] = min(dpmin[i][j - 1], dpmin[i + (1 << (j - 1))][j - 1]);
}
}
}
int query_min(int l, int r)
{
int k = log2(r - l + 1);
return min(dpmin[l][k], dpmin[r - (1 << k) + 1][k]);
}
int query_max(int l, int r)
{
int k = log2(r - l + 1);
return max(dpmax[l][k], dpmax[r - (1 << k) + 1][k]);
}
int main()
{
int T;
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &q[i]);
}
rmq();
bool xx = false;
for (int i = 1; i <= n - 2; i++)
{
bool flage = false;
int l = i + 1, r = n - 1;
int ans;
int lma = query_max(1, i);
while (r >= l)
{
int mid = (l + r) >> 1;
int mi = query_min(i + 1, mid);
if (mi == lma)
{
int rma = query_max(mid + 1, n);
if (rma == mi)
{
ans = mid;
flage = true;
break;
}
else if (mi > rma)//注意最大值是哪个
{
r = mid - 1;
}
else
{
l = mid + 1;
}
}
else
{
if (mi > lma)//注意最大值是哪个
{
l = mid + 1;
}
else
{
r = mid - 1;
}
}
}
if (flage)
{
xx = true;
printf("YES\n");
printf("%d %d %d\n", i, ans - i, n - ans);//l=i,y+x=ans,x+y+z=n;
break;
}
}
if (!xx)
{
printf("NO\n");
}
}
return 0;
}