Loading

Educational Codeforces Round 111 (Rated for Div. 2) C. Manhattan Subarrays(思维/暴力/好题)

Suppose you have two points 𝑝=(𝑥𝑝,𝑦𝑝)p=(xp,yp) and 𝑞=(𝑥𝑞,𝑦𝑞)q=(xq,yq). Let's denote the Manhattan distance between them as 𝑑(𝑝,𝑞)=|𝑥𝑝−𝑥𝑞|+|𝑦𝑝−𝑦𝑞|d(p,q)=|xp−xq|+|yp−yq|.

Let's say that three points 𝑝p, 𝑞q, 𝑟r form a bad triple if 𝑑(𝑝,𝑟)=𝑑(𝑝,𝑞)+𝑑(𝑞,𝑟)d(p,r)=d(p,q)+d(q,r).

Let's say that an array 𝑏1,𝑏2,…,𝑏𝑚b1,b2,…,bm is good if it is impossible to choose three distinct indices 𝑖i, 𝑗j, 𝑘k such that the points (𝑏𝑖,𝑖)(bi,i), (𝑏𝑗,𝑗)(bj,j)and (𝑏𝑘,𝑘)(bk,k) form a bad triple.

You are given an array 𝑎1,𝑎2,…,𝑎𝑛a1,a2,…,an. Calculate the number of good subarrays of 𝑎a. A subarray of the array 𝑎a is the array 𝑎𝑙,𝑎𝑙+1,…,𝑎𝑟al,al+1,…,arfor some 1≤𝑙≤𝑟≤𝑛1≤l≤r≤n.

Note that, according to the definition, subarrays of length 11 and 22 are good.

Input

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

The first line of each test case contains one integer 𝑛n (1≤𝑛≤2⋅1051≤n≤2⋅105) — the length of array 𝑎a.

The second line of each test case contains 𝑛n integers 𝑎1,𝑎2,…,𝑎𝑛a1,a2,…,an (1≤𝑎𝑖≤1091≤ai≤109).

It's guaranteed that the sum of 𝑛n doesn't exceed 2⋅1052⋅105.

Output

For each test case, print the number of good subarrays of array 𝑎a.

Example

input

Copy

3
4
2 4 1 3
5
6 9 1 9 6
2
13 37

output

Copy

10
12
3

我是脑瘫。。。想了半天不知道怎么维护,其实显然好序列最长只能为4,然后直接暴力即可。其实题目没要求模也可以知道答案最后不会很大。

证明:

等价于证明任何长度大于等于5的序列中必定含有长度大于等于3的单调不降/不增子序列,只需要证明长度为5的序列成立即可,显然成立(枚举下最大和最小的位置即可)。

#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, a[200005];
int judge(int l, int r) {
	if(r - l == 2) {//len == 3
		if(a[r] >= a[r - 1] && a[r - 1] >= a[r - 2] || a[r] <= a[r - 1] && a[r - 1] <= a[r - 2]) return 0;
		else return 1;
	} else {//len == 4
		if(
		a[r] >= a[r - 1] && a[r - 1] >= a[r - 2] || a[r] <= a[r - 1] && a[r - 1] <= a[r - 2] || 
		a[r] >= a[r - 1] && a[r - 1] >= a[r - 3] || a[r] <= a[r - 1] && a[r - 1] <= a[r - 3] || 
		a[r] >= a[r - 2] && a[r - 2] >= a[r - 3] || a[r] <= a[r - 2] && a[r - 2] <= a[r - 3] || 
		a[r - 1] >= a[r - 2] && a[r - 2] >= a[r - 3] || a[r - 1] <= a[r - 2] && a[r - 2] <= a[r - 3]
		) return 0;
		else return 1;
	}
}
signed main() {
	int t;
	cin >> t;
	while(t--) {
		cin >> n;
		for(int i = 1; i <= n; i++) {
			cin >> a[i];
		}
		int ans = 0;
		for(int i = 1; i <= n; i++) {
			for(int j = i; j <= min(i + 3, n); j++) {
				//判断左端点为i,右端点为j的区间是否为好区间
				if(j - i <= 1) ans++;
				else ans += judge(i, j);
			}
		}
		cout << ans << endl;
	}
	return 0;
}
posted @ 2021-07-15 20:02  脂环  阅读(359)  评论(0编辑  收藏  举报