假设有两点p = (p, yp)和q = (g,yg)。我们把它们之间的曼哈顿距离记为d(p,q) = p-l + yp-yl。如果d(p, r) = d(p, q) + d(q, r)那么p, q, r这三个点组成了一个坏的三元组。假设一个数组b1, b2,, bm是好的,如果它不可能选择三个不同的指标i, j, k,使得这些点和(bk, k)组成一个坏的三元组。(b, i), (b,j)已知一个数组a1, a2,。计算a的好子数组的个数。数组a的子数组是数组al, al+1,。, a,对于某个1 <l<r<n。注意,根据定义,长度为1和2的子数组是好的。输入第一行包含一个整数t (1 <t < 5000)——测试用例的数量。每个测试用例的第一行包含一个整数n (1 <n <2-105)-数组a的长度。每个测试用例的第二行包含n个整数a1, a2,。, an (1 < ai < 10°)。可以保证n的和不超过2 - 105。输出对于每个测试用例,打印数组a的良好子数组的数量。
Example
input
Copy
3 4 2 4 1 3 5 6 9 1 9 6 2 13 37
output
Copy
10 12 3
请注意在第一个测试用例中,可以证明a的任何子数组都是好的。例如,子数组[a2, as, a4]是很好的,因为它只包含三个元素,并且:d((a2, 2), (a4, 4)) = 14-3 +12-4 = 3 < d((a2, 2), (a3, 3)) + d((a3, 3), (a4, 4)) = 3+1+2+1 = 7;d ((a2,(2)、(a3, d (3) < (a2、(2)、(a4, d (4)) + (3) (a3、a4));d ((a3、a4 (3), (4) < d (a3、(3)、(a2) + d ((a4 a2、(2)、(4);例如,在第二个测试用例中,子数组[a1, @2, a3, a4)是不好的,因为它包含了一个坏的三元组(a1, 1), (a2, 2), (a4, 4):d((a1, 1), (a4, 4)) = 16-9|+|1- 4] = 6;d((a1, 1), (a2, 2)) = 16 - 9|+ |1 - 2|= 4;d ((a2、(2)、(4)a4) = 19 - 9 | + 12 - 4] = 2;So, d ((a1, 1), (a4, d (4) = (a1, 1), (a2, (2)) + d ((a4 a2、(2)、(4)。
题解:
遇到越是没有思路的题,越要从题目所给的条件中入手,没有思路,说明是没有读懂题意
看是否能把题目所给条件变形,或换推一下公式
结合题目给我们的式子,我们可以发现
假设i < j < k 三个点值为a , b ,c
x = |a - b| + |i - j| <=> x = |a - b| + j - i
y = |a - c| + |i - k| <=> y = |a - c| + k - i
z = |b - c| + |j - k|<=> z = |b - c| + k - j
如果a >= b >= c
x + z = y
如果a <= b <= c
依旧x + z = y
这就是我们所发现的规律
假如子串长度l
l = 1||l = 2,肯定是数组
l = 3如果出现上述情况,就不是好数组了
l = 4 子序列如果能组成上述情况,也不是好数组
l = 5,子序列一定会出现单调不下降,或单调不上升的情况所以一定不是好数组
#include<iostream>
#include<string>
#include<vector>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
int a[200050];
int check(int x,int y,int z)
{
if((x >= y&&y >= z)||(x <= y&&y <= z))
{
return 1;
}
else
{
return 0;
}
}
void solve()
{
int n;
scanf("%d",&n);
for(int i = 1;i <= n;i++)
{
scanf("%d",&a[i]);
}
int ans = 2*n - 1;
if(n >= 3)
{
for(int i = 1;i <= n - 2;i ++)
{
if(check(a[i],a[i+1],a[i+2]));
else
ans++;
}
}
if(n >= 4)
{
for(int i = 1;i <= n - 2;i++)
{
if(check(a[i],a[i+1],a[i+2])||check(a[i],a[i+1],a[i+3])||check(a[i],a[i+2],a[i+3])||check(a[i+1],a[i+2],a[i+3]));
else
ans++;
}
}
printf("%d\n",ans);
}
signed main()
{
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
int t = 1;
scanf("%d",&t);
while (t--)
{
solve();
}
return 0;
}