Sequence II
Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1435 Accepted Submission(s): 596
Problem Description
Long long ago, there is a sequence A with length n. All numbers in this sequence is no smaller than 1 and no bigger than n, and all numbers are different in this sequence.
Please calculate how many quad (a,b,c,d) satisfy:
1. 1≤a<b<c<d≤n
2. Aa<Ab
3. Ac<Ad
Input
The first line contains a single integer T, indicating the number of test cases.
Each test case begins with a line contains an integer n.
The next line follows n integers A1,A2,…,An.
[Technical Specification]
1 <= T <= 100
1 <= n <= 50000
1 <= Ai <= n
Output
For each case output one line contains a integer,the number of quad.
Sample Input
1 5 1 3 2 4 5
Sample Output
4
Source
Recommend
heyang | We have carefully selected several similar problems for you: 6447 6446 6445 6444 6443
#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;
#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define ll long long
const int maxn =1e5+5;
const int mod=1e9+7;
///树状数组
int tree[maxn];
int lowbit(int x){return x&(-x);}
ll sum(int x){ll ret=0;for(;x>0;ret+=1LL*tree[x],x-=lowbit(x));return ret;}
void add(int x,int d){for(;x<maxn;tree[x]+=d,x+=lowbit(x));}
ll mark1[maxn],mark2[maxn];///记录数组
int a[maxn],n;
/*
题目大意:统计四元组,该四元组满足前两个数和后两个数按序号递增。
很明显树状数组维护,
首先思考如何唯一的计数一个四元组,
如果确定了第一个二元组的第二个数,那么包含这个数的四元组
就是前面比这个数小的数的个数*后面的二元组对数(大小关系)。
那么思路大致有了,先树状数组维护出来比当前数字小的前面的数字个数,
再类似的倒叙维护一遍,然后把倒叙维护出来的数组统计前缀和。
按序扫一遍计数答案就行了。
*/
int main()
{
int t;scanf("%d",&t);
while(t--)
{
scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]);
memset(tree,0,sizeof(tree));
for(int i=1;i<=n;i++)
{
mark1[i]=sum(a[i]);
add(a[i],1);
}
memset(tree,0,sizeof(tree));
for(int i=n;i>=1;i--)
{
mark2[i]=sum(n)-sum(a[i]-1);
add(a[i],1);
}
ll ans=0; mark2[n+1]=0;
for(int i=n;i>=1;i--) mark2[i]+=mark2[i+1];
for(int i=1;i<=n;i++) if(mark1[i]) ans+=1LL*mark1[i]*mark2[i+1];
printf("%lld\n",ans);
}
return 0;
}