时津风有一个长度为n的排列组合p。回顾一下,长度为n的排列组合p是由n个不同的整数组成的序列p1,p2,...,pn,每个整数从1到n(1≤pi≤n)。
她想知道在这个排列组合中,有多少个不同的指数图组[a,b,c,d](1≤a不等式。
pa
请注意,如果a1≠a2或b1≠b2或c1≠c2或d1≠d2,两个图元[a1,b1,c1,d1]被认为是不同的。
输入
第一行包含一个整数t(1≤t≤1000)--测试案例的数量。每个测试用例由两行组成。
第一行包含一个整数n(4≤n≤5000)--包络的长度p。
第二行包含n个整数p1,p2,...,pn(1≤pi≤n)--包络p。
保证所有测试案例的n之和不超过5000。
输出
对于每个测试案例,打印一个整数--不同的[a,b,c,d]图组的数量。
例子
输入复制
3
6
5 3 6 1 4 2
4
1 2 3 4
10
5 1 6 2 8 3 4 10 9 7
输出拷贝
3
0
28
注意
在第一个测试案例中,有3个不同的[a,b,c,d]图组。
p1=5, p2=3, p3=6, p4=1,其中p1
同样地,另外两个图元是[1,2,3,6],[2,3,5,6]。
题解:
我们可以枚举b,过程中,利用桶排的思想把对b前面的数标记,利用前缀和,找到,b后面的数c有多少个是大于a的res,然后在内部循环,c后面的数,找到大于当前b的加上,然后更新res,因为b后面的数可以成为d,也可以为c
(说的有点乱,具体代码有体现)
- #include<iostream>
- #include<algorithm>
- #include<cstring>
- #include<string>
- #include<map>
- #include<vector>
- #include<queue>
- using namespace std;
- #define int long long
- //1 1 3 3 3
- int n,ans;
- int a[200050];
- int tong[5005];
- int d[5005];
- void solve()
- {
- int n;
- cin >> n;
- for(int i = 1;i <= n;i++)
- cin >> a[i],tong[i] = 0;
- int ans = 0,res;
- for(int i = 2;i < n-1;i++)(枚举b的位置)
- {
- tong[a[i-1]]++;(对a的位置进行桶排标记)
- for(int j = 1;j <= n;j++)
- {
- d[j] = d[j-1] + tong[j];(统计每个位置大于前面的有几个数)
- }
- res = d[a[i+1]];//得到c大于a的个数
- for(int j = i+2;j <= n; j++)//枚举d
- {
- if(a[i] > a[j])//如果b > d
- {
- ans += res;
- }
- res += d[a[j]];//更新res如果a[j]前面有数,说明这个数也可以a[j]也可以为c
- }
- }
- cout<<ans<<"\n";
- }
- signed main()
- {
- int t = 1;
- cin >> t;
- while(t--)
- {
- solve();
- }
- }
- //2 5
- //3
- //9 7
-
-
- //2 3 4 3
- //1 2 3 4 5
- // 3