#include<bits/stdc++.h>
using namespace std;

#ifdef LOCAL
#include "debug.h"
#endif

#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef std::vector<vector<int> > vvi;
typedef pair<int, int> pi;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;
typedef vector<pi> vpi;
typedef vector<pll> vpll;
typedef vector<vll> vvll;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vector<double>> vvd;
typedef vector<ld> vld;
typedef vector<vld> vvld;
typedef vector<bool> vb;
typedef vector<vb> vvb;


#define rep(i, a, b) for (int i = (int)a; i < (int)b; i++)
#define repi(i, a, b) for (int i = (int)a; i >= (int)b; i--)
#define pb push_back
#define fi first
#define se second
#define all(a) a.begin(), a.end()
#define sz(a) (int)(a.size())
#define umin(a, x) a = min(a, x)
#define umax(a, x) a = max(a, x)

ll nxt() {
	ll x; cin >> x; return x;
}

void setIO(string s) {
	#ifndef LOCAL
	ios_base::sync_with_stdio(0); cin.tie(0); 
	freopen((s+".in").c_str(),"r",stdin);
	freopen((s+".out").c_str(),"w",stdout);
	#endif
}


const int inf = 1e9;
struct SegmentTree
{	
	vi a, t;
	int n;

	SegmentTree(int n): n(n){
		a.resize(n+1, inf);
		t.resize(4*n+1, inf);
	}

	void update(int pos, int val){
		updatehelper(pos, val, 1, 1, n); //pos, val, node, left, right 
		//node is the index in the tree
	}

	int get(int l, int r){
		return gethelper(l, r, 1, 1, n);
	}

	void updatehelper(int pos, int val, int node, int left, int right){
		if(pos < left || pos > right) return;
		else if(left == right){
			a[pos] = val;
			t[node] = val;
		}
		else{
			updatehelper(pos, val, 2*node, left, (left+right)/2);
			updatehelper(pos, val, 2*node + 1, (left+right)/2 + 1, right);
			t[node] = min(t[2*node], t[2*node+1]);
		}
	}

	int gethelper(int l, int r, int node, int left, int right){
		if(r < left || l > right) return inf;
		else if( l <= left && right <= r) return t[node];
		else{
			return min(gethelper(l, r, 2*node, left, (left + right)/2), gethelper(l, r, 2*node+1, (left+right)/2 + 1, right));
		}
	}
};

void solve() {
	int n = nxt();
	SegmentTree seg(n + 2);
	vi a(n + 1); rep(i, 1, n + 1) {
		cin >> a[i];
		seg.update(i, a[i]);
	}

	vi pref_max(n + 2), suf_max(n + 2);
	map<int, int> first_occ, last_occ;

	rep(i, 1, n + 1) {
		pref_max[i] = max(pref_max[i - 1], a[i]);
		int x = suf_max[n - i + 1] = max(suf_max[n - i + 2], a[n - i + 1]);
		if (!last_occ.count(x)) {
			last_occ[x] = n - i + 1;
		}
		first_occ[x] = n - i + 1;
	}

	suf_max[0] = inf;
	vi negs = suf_max;
	rep(i, 0, sz(negs)) negs[i] = -suf_max[i];


	debug("###############");
	debug(n, a);

	debug(suf_max);
	debug(first_occ);	
	debug(last_occ);

	rep(x, 1, n - 1) {
		int cur = pref_max[x];
		int id1, id2;
		if (first_occ.count(cur)) {
			id1 = first_occ[cur];
			id2 = last_occ[cur];
			id1 = max(x + 1, id1);
			if (id2 < id1) continue;
		} else {
			continue;
		}

		int lo = max(id1 - 1, x + 1), hi = max(id2 - 1, x + 1);
		assert(id1 >= x + 1 && id1 <= id2);


		debug(x, cur, lo, hi);

		while (lo < hi) {
			int mid = (lo + hi) / 2;
			int mn = seg.get(x + 1, mid);
			if (mn > cur) {
				lo = mid + 1;
			} else {
				hi = mid;
			}
		}

		assert(lo == hi);
		if (lo >= x + 1 && lo < id2 && seg.get(x + 1, lo) == cur) {
			cout << "YES\n";
			int y = lo - x, z = n - lo;
			cout << x << " " << lo - x << " " << n - lo << "\n";

			debug(id1, id2, cur);


			assert(x >= 1 && y >= 1 && z >= 1 && x + y + z == n);
			assert(pref_max[x] == suf_max[n - z + 1] 
				&& pref_max[x] == seg.get(x + 1, x + y));
			return;
		}
	}

	cout << "NO\n";


}	
	
int32_t main(){
	// setIO("trapped");
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	cout << fixed << setprecision(10);

	int T = 1;
	cin >> T;

	for (int tc = 1; tc <= T; tc++) {
		// cout << "Case #" << tc << ": ";
		solve();
	}
}
