Codeforces Round #686 (Div. 3) A~F

A. Special Permutation

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given one integer nn (n>1n>1).

Recall that a permutation of length nn is an array consisting of nn distinct integers from 11 to nn in arbitrary order. For example, [2,3,1,5,4][2,3,1,5,4] is a permutation of length 55, but [1,2,2][1,2,2] is not a permutation (22 appears twice in the array) and [1,3,4][1,3,4] is also not a permutation (n=3n=3 but there is 44 in the array).

Your task is to find a permutation pp of length nn that there is no index ii (1≤i≤n1≤i≤n) such that pi=ipi=i (so, for all ii from 11 to nn the condition pi≠ipi≠i should be satisfied).

You have to answer tt independent test cases.

If there are several answers, you can print any. It can be proven that the answer exists for each n>1n>1.

Input

The first line of the input contains one integer tt (1≤t≤1001≤t≤100) — the number of test cases. Then tt test cases follow.

The only line of the test case contains one integer nn (2≤n≤1002≤n≤100) — the length of the permutation you have to find.

Output

For each test case, print nn distinct integers p1,p2,…,pnp1,p2,…,pn — a permutation that there is no index ii (1≤i≤n1≤i≤n) such that pi=ipi=i (so, for all ii from 11 to nn the condition pi≠ipi≠i should be satisfied).

If there are several answers, you can print any. It can be proven that the answer exists for each n>1n>1.

Example

input

Copy

2
2
5

output

Copy

2 1
2 1 5 3 4

题目大意:

    构造一个排列,使得不存在第i个数为i。

解法:

    按照2,3,4……n - 1, n, 1构造即可。

Accpeted code

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define sc scanf
#define Min(x, y) x = min(x, y)
#define Max(x, y) x = max(x, y)
#define ALL(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define pir pair <int, int>
#define MK(x, y) make_pair(x, y)
#define MEM(x, b) memset(x, b, sizeof(x))
#define MPY(x, b) memcpy(x, b, sizeof(x))
#define lowbit(x) ((x) & -(x))
#define P2(x) ((x) * (x))

typedef long long ll;
const int Mod = 1e9 + 7;
const int N = 1e5 + 100;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
inline ll dpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % Mod; b >>= 1; t = (t*t) % Mod; }return r; }
inline ll fpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t); b >>= 1; t = (t*t); }return r; }



int main()
{
	int T; cin >> T;
	while (T--) {
		int n;
		cin >> n;
		for (int i = 2; i <= n; i++)
			cout << i << ' ';
		cout << 1 << endl;
	}
	return 0; // 改数组大小!!!用pair改宏定义!!!
}

B. Unique Bid Auction

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

There is a game called "Unique Bid Auction". You can read more about it here: https://en.wikipedia.org/wiki/Unique_bid_auction (though you don't have to do it to solve this problem).

Let's simplify this game a bit. Formally, there are nn participants, the ii-th participant chose the number aiai. The winner of the game is such a participant that the number he chose is unique (i. e. nobody else chose this number except him) and is minimal (i. e. among all unique values of aa the minimum one is the winning one).

Your task is to find the index of the participant who won the game (or -1 if there is no winner). Indexing is 11-based, i. e. the participants are numbered from 11 to nn.

You have to answer tt independent test cases.

Input

The first line of the input contains one integer tt (1≤t≤2⋅1041≤t≤2⋅104) — the number of test cases. Then tt test cases follow.

The first line of the test case contains one integer nn (1≤n≤2⋅1051≤n≤2⋅105) — the number of participants. The second line of the test case contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤n1≤ai≤n), where aiai is the ii-th participant chosen number.

It is guaranteed that the sum of nn does not exceed 2⋅1052⋅105 (∑n≤2⋅105∑n≤2⋅105).

Output

For each test case, print the answer — the index of the participant who won the game (or -1 if there is no winner). Note that the answer is always unique.

Example

input

Copy

6
2
1 1
3
2 1 3
4
2 2 2 3
1
1
5
2 3 2 4 2
6
1 1 5 5 4 4

output

Copy

-1
2
4
1
2
-1

题目大意:

    给出每个人选的东西,输出只选了一个东西且编号最小的人,若没有输出-1.

解法:

    直接模拟。

Accepted code

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define sc scanf
#define Min(x, y) x = min(x, y)
#define Max(x, y) x = max(x, y)
#define ALL(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define pir pair <int, int>
#define MK(x, y) make_pair(x, y)
#define MEM(x, b) memset(x, b, sizeof(x))
#define MPY(x, b) memcpy(x, b, sizeof(x))
#define lowbit(x) ((x) & -(x))
#define P2(x) ((x) * (x))

typedef long long ll;
const int Mod = 1e9 + 7;
const int N = 2e5 + 100;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
inline ll dpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % Mod; b >>= 1; t = (t*t) % Mod; }return r; }
inline ll fpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t); b >>= 1; t = (t*t); }return r; }

vector <int> G[N];
int n;

void Init() {
	for (int i = 1; i <= n; i++)
		G[i].clear();
}

int main()
{
	int T; cin >> T;
	while (T--) {
		cin >> n;
		Init();
		for (int i = 1; i <= n; i++) {
			int t;
			cin >> t;
			G[t].push_back(i);
		}
		int ans = -1;
		for (int i = 1; i <= n; i++) {
			if (SZ(G[i]) == 1) {
				ans = G[i][0];
				break;
			}
		}
		cout << ans << endl;
	}
	return 0; // 改数组大小!!!用pair改宏定义!!!
}

C. Sequence Transformation

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given a sequence aa, initially consisting of nn integers.

You want to transform this sequence so that all elements in it are equal (i. e. it contains several occurrences of the same element).

To achieve this, you choose some integer xx that occurs at least once in aa, and then perform the following operation any number of times (possibly zero): choose some segment [l,r][l,r] of the sequence and remove it. But there is one exception: you are not allowed to choose a segment that contains xx. More formally, you choose some contiguous subsequence [al,al+1,…,ar][al,al+1,…,ar] such that ai≠xai≠x if l≤i≤rl≤i≤r, and remove it. After removal, the numbering of elements to the right of the removed segment changes: the element that was the (r+1)(r+1)-th is now ll-th, the element that was (r+2)(r+2)-th is now (l+1)(l+1)-th, and so on (i. e. the remaining sequence just collapses).

Note that you can not change xx after you chose it.

For example, suppose n=6n=6, a=[1,3,2,4,1,2]a=[1,3,2,4,1,2]. Then one of the ways to transform it in two operations is to choose x=1x=1, then:

  1. choose l=2l=2, r=4r=4, so the resulting sequence is a=[1,1,2]a=[1,1,2];
  2. choose l=3l=3, r=3r=3, so the resulting sequence is a=[1,1]a=[1,1].

Note that choosing xx is not an operation. Also, note that you can not remove any occurrence of xx.

Your task is to find the minimum number of operations required to transform the sequence in a way described above.

You have to answer tt independent test cases.

Input

The first line of the input contains one integer tt (1≤t≤2⋅1041≤t≤2⋅104) — the number of test cases. Then tt test cases follow.

The first line of the test case contains one integer nn (1≤n≤2⋅1051≤n≤2⋅105) — the number of elements in aa. The second line of the test case contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤n1≤ai≤n), where aiai is the ii-th element of aa.

It is guaranteed that the sum of nn does not exceed 2⋅1052⋅105 (∑n≤2⋅105∑n≤2⋅105).

Output

For each test case, print the answer — the minimum number of operations required to transform the given sequence in a way described in the problem statement. It can be proven that it is always possible to perform a finite sequence of operations so the sequence is transformed in the required way.

Example

input

Copy

5
3
1 1 1
5
1 2 3 4 5
5
1 2 3 2 1
7
1 2 3 1 2 3 1
11
2 2 1 2 3 2 1 2 3 1 2

output

Copy

0
1
1
2
3

题目大意:

    给你一个长度为n的数组,数据范围1~n,你要先选择一个数x,然后删除所有不存在x的区间,问最少删多少次能够使得数组只剩下x。

解法:

    先预处理一下,把连续且相同的数缩成一个,然后把新数组的每个数的位置存下来,最后对于同一个数,看他在数组中的位置求一下间隔就好。

Accpeted code

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define sc scanf
#define Min(x, y) x = min(x, y)
#define Max(x, y) x = max(x, y)
#define ALL(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define pir pair <int, int>
#define MK(x, y) make_pair(x, y)
#define MEM(x, b) memset(x, b, sizeof(x))
#define MPY(x, b) memcpy(x, b, sizeof(x))
#define lowbit(x) ((x) & -(x))
#define P2(x) ((x) * (x))

typedef long long ll;
const int Mod = 1e9 + 7;
const int N = 2e5 + 100;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
inline ll dpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % Mod; b >>= 1; t = (t*t) % Mod; }return r; }
inline ll fpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t); b >>= 1; t = (t*t); }return r; }

vector <int> G[N];
int a[N], b[N], n;

int main()
{
	int T; cin >> T;
	while (T--) {
		sc("%d", &n);
		set <int> st;
		for (int i = 1; i <= n; i++)
			sc("%d", &a[i]), G[i].clear(), st.insert(a[i]);
		if (SZ(st) == 1) {
			puts("0");
			continue;
		}

		int cnt = 0;
		b[++cnt] = a[1];
		for (int i = 2; i <= n; i++) {  // 预处理
			if (a[i] != a[i - 1]) 
				b[++cnt] = a[i];
		}

		int mi = INF;
		for (int i = 1; i <= cnt; i++)  // 每个数的位置
			G[b[i]].push_back(i);
		for (int i = 1; i <= n; i++) {
			if (G[i].empty())
				continue;
			int tot = 0;
			if (G[i][0] != 1)  // 特判开头
				tot++;
			if (G[i][SZ(G[i]) - 1] != cnt)  // 特判末尾
				tot++;
			if (SZ(G[i]) > 1)
				tot += SZ(G[i]) - 1;
			Min(mi, tot);
		}
		cout << mi << endl;
	}
	return 0; // 改数组大小!!!用pair改宏定义!!!
}

D. Number into Sequence

time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given an integer nn (n>1n>1).

Your task is to find a sequence of integers a1,a2,…,aka1,a2,…,ak such that:

  • each aiai is strictly greater than 11;
  • a1⋅a2⋅…⋅ak=na1⋅a2⋅…⋅ak=n (i. e. the product of this sequence is nn);
  • ai+1ai+1 is divisible by aiai for each ii from 11 to k−1k−1;
  • kk is the maximum possible (i. e. the length of this sequence is the maximum possible).

If there are several such sequences, any of them is acceptable. It can be proven that at least one valid sequence always exists for any integer n>1n>1.

You have to answer tt independent test cases.

Input

The first line of the input contains one integer tt (1≤t≤50001≤t≤5000) — the number of test cases. Then tt test cases follow.

The only line of the test case contains one integer nn (2≤n≤10102≤n≤1010).

It is guaranteed that the sum of nn does not exceed 10101010 (∑n≤1010∑n≤1010).

Output

For each test case, print the answer: in the first line, print one positive integer kk — the maximum possible length of aa. In the second line, print kk integers a1,a2,…,aka1,a2,…,ak — the sequence of length kk satisfying the conditions from the problem statement.

If there are several answers, you can print any. It can be proven that at least one valid sequence always exists for any integer n>1n>1.

Example

input

Copy

4
2
360
4999999937
4998207083

output

Copy

1
2 
3
2 2 90 
1
4999999937 
1
4998207083 

题目大意:

    给你一个数X,你要输出一个最长的序列,使得每个元素都 > 1,并且除了第一个元素外,每个元素都能整除前一个数,且序列所有数的乘积为X。

解法:

    所有数乘积为X,不难想到要拆分质因子;

    每个元素都能整除前一个,说明当前元素的值一定得包含上一个元素作为因子;

    然后要求最长,贪心一下就知道答案就是最多因子的个数,假如选了s个因子t,那么最后一个t就要与其他所有因子相乘才能保证整除。

Accepted code

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define sc scanf
#define Min(x, y) x = min(x, y)
#define Max(x, y) x = max(x, y)
#define ALL(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define pir pair <int, int>
#define MK(x, y) make_pair(x, y)
#define MEM(x, b) memset(x, b, sizeof(x))
#define MPY(x, b) memcpy(x, b, sizeof(x))
#define lowbit(x) ((x) & -(x))
#define P2(x) ((x) * (x))

typedef long long ll;
const int Mod = 1e9 + 7;
const int N = 1e5 + 100;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
inline ll dpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % Mod; b >>= 1; t = (t*t) % Mod; }return r; }
inline ll fpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t); b >>= 1; t = (t*t); }return r; }

int main()
{
	int T; cin >> T;
	while (T--) {
		ll n;
		sc("%lld", &n);
		map <ll, int> cnt;
		for (ll i = 2; i * i <= n; i++) {
			ll x = i;
			if (n % x == 0) {
				while (n % x == 0)
					cnt[x]++, n /= x;
			}
		}
		if (n > 1)
			cnt[n]++;    // 拆分质因子
		int mx = 0; ll s;
		for (auto it : cnt) {   // 找到最多的
			if (it.second > mx)
				s = it.first, mx = it.second;
		}
		printf("%d\n", mx);
		for (int i = 0; i < mx - 1; i++)
			printf("%lld ", s);
		ll t = s;
		for (auto it : cnt) {
			if (it.first == t)
				continue;
			for (int j = 0; j < it.second; j++)
				s *= it.first;  // 其余的相乘
		}
		printf("%lld\n", s);
	}
	return 0; // 改数组大小!!!用pair改宏定义!!!
}

E. Number of Simple Paths

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given an undirected graph consisting of nn vertices and nn edges. It is guaranteed that the given graph is connected (i. e. it is possible to reach any vertex from any other vertex) and there are no self-loops and multiple edges in the graph.

Your task is to calculate the number of simple paths of length at least 11 in the given graph. Note that paths that differ only by their direction are considered the same (i. e. you have to calculate the number of undirected paths). For example, paths [1,2,3][1,2,3] and [3,2,1][3,2,1] are considered the same.

You have to answer tt independent test cases.

Recall that a path in the graph is a sequence of vertices v1,v2,…,vkv1,v2,…,vk such that each pair of adjacent (consecutive) vertices in this sequence is connected by an edge. The length of the path is the number of edges in it. A simple path is such a path that all vertices in it are distinct.

Input

The first line of the input contains one integer tt (1≤t≤2⋅1041≤t≤2⋅104) — the number of test cases. Then tt test cases follow.

The first line of the test case contains one integer nn (3≤n≤2⋅1053≤n≤2⋅105) — the number of vertices (and the number of edges) in the graph.

The next nn lines of the test case describe edges: edge ii is given as a pair of vertices uiui, vivi (1≤ui,vi≤n1≤ui,vi≤n, ui≠viui≠vi), where uiui and vivi are vertices the ii-th edge connects. For each pair of vertices (u,v)(u,v), there is at most one edge between uu and vv. There are no edges from the vertex to itself. So, there are no self-loops and multiple edges in the graph. The graph is undirected, i. e. all its edges are bidirectional. The graph is connected, i. e. it is possible to reach any vertex from any other vertex by moving along the edges of the graph.

It is guaranteed that the sum of nn does not exceed 2⋅1052⋅105 (∑n≤2⋅105∑n≤2⋅105).

Output

For each test case, print one integer: the number of simple paths of length at least 11 in the given graph. Note that paths that differ only by their direction are considered the same (i. e. you have to calculate the number of undirected paths).

Example

input

Copy

3
3
1 2
2 3
1 3
4
1 2
2 3
3 4
4 2
5
1 2
2 3
1 3
2 5
4 3

output

Copy

6
11
18

Note

Consider the second test case of the example. It looks like that:

 

There are 1111 different simple paths:

  1. [1,2][1,2];
  2. [2,3][2,3];
  3. [3,4][3,4];
  4. [2,4][2,4];
  5. [1,2,4][1,2,4];
  6. [1,2,3][1,2,3];
  7. [2,3,4][2,3,4];
  8. [2,4,3][2,4,3];
  9. [3,2,4][3,2,4];
  10. [1,2,3,4][1,2,3,4];
  11. [1,2,4,3][1,2,4,3].

 

题目大意:

    给你一颗n个点的联通的基环树,输出有多少条不同的简单路径。

解法:

    比赛看错题了,没注意到基环树这个条件QAQ

    假如整个图都是一个环,每个点都与其他点有一个路径,那么答案就是n * (n - 1)

    现在是基环树,可能存在两点间只有一条路径的情况,容易发现就是基环树的子树的点,这时候只要求出所有子树的点数(包含基环树上的一个点),然后减去他们多算的一条路径就好。

Accepted code

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define sc scanf
#define Min(x, y) x = min(x, y)
#define Max(x, y) x = max(x, y)
#define ALL(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define pir pair <int, int>
#define MK(x, y) make_pair(x, y)
#define MEM(x, b) memset(x, b, sizeof(x))
#define MPY(x, b) memcpy(x, b, sizeof(x))
#define lowbit(x) ((x) & -(x))
#define P2(x) ((x) * (x))

typedef long long ll;
const int Mod = 1e9 + 7;
const int N = 2e5 + 100;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
inline ll dpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % Mod; b >>= 1; t = (t*t) % Mod; }return r; }
inline ll fpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t); b >>= 1; t = (t*t); }return r; }

vector <int> G[N];
int pre[N], n;
bool vis[N], cur[N], ok;

void Init() {
	for (int i = 1; i <= n; i++) {
		G[i].clear();
		vis[i] = cur[i] = pre[i] = 0;
	}
	ok = false;
}
void DFS(int x, int fa) {
	if (ok)
		return;
	vis[x] = 1;
	for (auto v : G[x]) {
		if (v == fa)
			continue;
		if (!vis[v])
			pre[v] = x, DFS(v, x);
		else {
			if (ok)
				return;
			for (int i = x; i != v; i = pre[i])
				cur[i] = true;
			cur[v] = true;
			ok = true;
		}
	}
}
void DFS1(int x, int fa, int &cnt) {
	for (auto v : G[x]) {
		if (!cur[v] && v != fa)
			cnt++, DFS1(v, x, cnt);
	}
}

int main()
{
	int T; cin >> T;
	while (T--) {
		sc("%d", &n);
		Init();
		for (int i = 1; i <= n; i++) {
			int u, v;
			sc("%d %d", &u, &v);
			G[u].push_back(v);
			G[v].push_back(u);
		}
		DFS(1, 0);  // 找环

		ll ans = 1ll * n * (n - 1);  // 初始答案
		for (int i = 1; i <= n; i++) {
			if (cur[i]) {
				int cnt = 1;
				DFS1(i, 0, cnt);
				ans -= 1ll * cnt * (cnt - 1) / 2;  // 减去子树多算的路径
			}
		}
		printf("%lld\n", ans);
	}
	return 0; // 改数组大小!!!用pair改宏定义!!!
}

F. Array Partition

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given an array aa consisting of nn integers.

Let min(l,r)min(l,r) be the minimum value among al,al+1,…,aral,al+1,…,ar and max(l,r)max(l,r) be the maximum value among al,al+1,…,aral,al+1,…,ar.

Your task is to choose three positive (greater than 00) integers xx, yy and zz such that:

  • x+y+z=nx+y+z=n;
  • max(1,x)=min(x+1,x+y)=max(x+y+1,n)max(1,x)=min(x+1,x+y)=max(x+y+1,n).

In other words, you have to split the array aa into three consecutive non-empty parts that cover the whole array and the maximum in the first part equals the minimum in the second part and equals the maximum in the third part (or determine it is impossible to find such a partition).

Among all such triples (partitions), you can choose any.

You have to answer tt independent test cases.

Input

The first line of the input contains one integer tt (1≤t≤2⋅1041≤t≤2⋅104) — the number of test cases. Then tt test cases follow.

The first line of the test case contains one integer nn (3≤n≤2⋅1053≤n≤2⋅105) — the length of aa.

The second line of the test case contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109), where aiai is the ii-th element of aa.

It is guaranteed that the sum of nn does not exceed 2⋅1052⋅105 (∑n≤2⋅105∑n≤2⋅105).

Output

For each test case, print the answer: NO in the only line if there is no such partition of aa that satisfies the conditions from the problem statement. Otherwise, print YES in the first line and three integers xx, yy and zz (x+y+z=nx+y+z=n) in the second line.

If there are several answers, you can print any.

Example

input

Copy

6
11
1 2 3 3 3 4 4 3 4 2 1
8
2 9 1 7 3 9 4 1
9
2 1 4 2 4 3 3 1 2
7
4 2 1 1 4 1 4
5
1 1 1 1 1
7
4 3 4 3 3 3 4

output

Copy

YES
6 1 4
NO
YES
2 5 2
YES
4 1 2
YES
1 1 3
YES
2 1 4

题目大意:

    给你一个数组,你要将他分成连续的三段S1,S2,S3,使得max(S1) = min(S2) = max(S3),输出分成三段的长度。

解法:

    这个题读完就会了,S1和S3的最大值可以用前缀最大值、后缀最大值来表示,中间的min需要查询区间最小值。

    那么我们从1开始遍历,假设当前遍历到的i就是S1与S2的分界线,此时前缀最大值是mx1,因为后缀最大值要与mx1相等,所以二分一下S2与S3的分界位置,查询中间的最小值Min,此时有三种情况:

    1、Min比mx1小,这时候肯定无解。

    2、Min = mx1,这时候答案已经出了。

    3、Min > mx1,此时需要将S2与S3分界线右移,如果可以右移那么答案也满足。

Accepted code

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;

#define sc scanf
#define Min(x, y) x = min(x, y)
#define Max(x, y) x = max(x, y)
#define ALL(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define pir pair <int, int>
#define MK(x, y) make_pair(x, y)
#define MEM(x, b) memset(x, b, sizeof(x))
#define MPY(x, b) memcpy(x, b, sizeof(x))
#define lowbit(x) ((x) & -(x))
#define P2(x) ((x) * (x))

typedef long long ll;
const int Mod = 1e9 + 7;
const int N = 2e5 + 100;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
inline ll dpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t) % Mod; b >>= 1; t = (t*t) % Mod; }return r; }
inline ll fpow(ll a, ll b){ ll r = 1, t = a; while (b){ if (b & 1)r = (r*t); b >>= 1; t = (t*t); }return r; }

int mx[N * 4], mx2[N], a[N], n;
vector <int> m2[N], pos[N], ver;

#define ls (o << 1)
#define rs (ls | 1)
void Init() {
	for (int i = 0; i <= n + 1; i++)
		mx2[i] = 0, m2[i].clear(), pos[i].clear();
	ver.clear();
}
void Lis() {
	sort(ALL(ver));
	ver.erase(unique(ALL(ver)), ver.end());
	for (int i = 1; i <= n; i++)
		a[i] = lower_bound(ALL(ver), a[i]) - ver.begin() + 1;  // 离散化

	for (int i = n; i >= 1; i--) {
		mx2[i] = max(mx2[i + 1], a[i]);  // 后缀最大值
		m2[mx2[i]].push_back(i);     // 后缀最大值的位置
		if (mx2[i] == a[i])
			pos[mx2[i]].push_back(i);  // 存下标方便二分查找
	}
	for (int i = 1; i <= n; i++)
		reverse(ALL(m2[i])), reverse(ALL(pos[i]));
}
void Build(int o, int L, int R) {
	if (L == R)
		mx[o] = a[L];
	else {
		int mid = (L + R) >> 1;
		Build(ls, L, mid), Build(rs, mid + 1, R);
		mx[o] = min(mx[ls], mx[rs]);
	}
}
int Ask(int o, int L, int R, int l, int r) {
	if (L >= l && R <= r)
		return mx[o];
	else {
		int mid = (L + R) >> 1;
		int ans = INF;
		if (mid >= l)
			Min(ans, Ask(ls, L, mid, l, r));
		if (mid < r)
			Min(ans, Ask(rs, mid + 1, R, l, r));
		return ans;
	}
}

int main()
{
	int T; cin >> T;
	while (T--) {
		sc("%d", &n);
		Init();
		for (int i = 1; i <= n; i++)
			sc("%d", &a[i]), ver.push_back(a[i]);
		Lis(), Build(1, 1, n);  // 预处理
		 
		int mx1 = 0;
		int l = 0, r = 0, mid = 0;
		for (int i = 1; i <= n && !l; i++) {
			Max(mx1, a[i]);
			auto nxt = lower_bound(ALL(m2[mx1]), i + 2) - m2[mx1].begin();
			if (nxt == SZ(m2[mx1]))  // 没找到
				continue;
			int mi = Ask(1, 1, n, i + 1, m2[mx1][nxt] - 1);
			if (mi == mx1)   // 第二种情况
				l = i, mid = m2[mx1][nxt] - 1 - i, r = n - m2[mx1][nxt] + 1;
			else if (mi > mx1) {  // 第三种情况
				auto nxt1 = lower_bound(ALL(pos[mx1]), m2[mx1][nxt]) - pos[mx1].begin();
				if (nxt1 < SZ(pos[mx1]) - 1 && Ask(1, 1, n, i + 1, pos[mx1][nxt1]) == mx1)
					l = i, mid = pos[mx1][nxt1] - i, r = n - pos[mx1][nxt1];
			}
		}
		if (!l)
			puts("NO");
		else {
			puts("YES");
			printf("%d %d %d\n", l, mid, r);
		}
	}
	return 0; // 改数组大小!!!用pair改宏定义!!!
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值