Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
Problem Description
Given a sequence A with length n,count how many quadruple (a,b,c,d) satisfies: a≠b≠c≠d,1≤a< b≤n, 1≤c< d≤n,Aa< Ab,Ac>Ad.
Input
The input consists of multiple test cases.
Each test case begin with an integer n in a single line.
The next line contains n integers A1,A2⋯An.
1≤n≤50000
0≤Ai≤1e9
Output
For each test case,output a line contains an integer.
Sample Input
4
2 4 1 3
4
1 2 3 4
Sample Output
1
0
题目意思是说,给你n个数,要满足条件:
a≠b≠c≠d,1≤a< b≤n,1≤c< d≤n,Aa< Ab,Ac>Ad
这道题,其实是有个公式的,说的容斥问题,但是如果把数据的情况全部列出来,然后再想想,就可以知道:
所有的情况是,每个数的前面比他大的数字的数目的总和*每个数的前面比他小的数字的数目的总和
但是这个总和是有不符合条件的
不符合条件的数目是:
对于每个数字:
(前面比他小的数目+后面比他大的数目)(前面比他大的数目)(后面比他小的数目)
拿总共所有的情况减去上述情况就行。
这道题一直卡在树状数组那里,然后,睡了一觉,脑子清醒了,然后就搞定了
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
#include<map>
#define ll long long
#define maxn 50010
using namespace std;
int zbig[maxn];
int zsmall[maxn];
int ybig[maxn];
int ysmall[maxn];
int tree[maxn];
int num[maxn];
int a[maxn];
int n;
ll ans;
map <ll,ll> m;
int lowbit(int x)
{
return x&(-x);
}
void update(int x)
{
while(x<maxn)
{
tree[x]++;
x+=lowbit(x);
}
}
int getsum(int x)
{
int sum=0;
while(x)
{
sum+=tree[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&num[i]);
a[i]=num[i];
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++) m[a[i]]=i;
for(int i=1;i<=n;i++) num[i]=m[num[i]];
// for(int i=1;i<=n;i++) cout<<num[i]<<" "; cout<<endl;
ll r=0,l=0;
memset(tree,0,sizeof(tree));
for(int i=1;i<=n;i++)
{
zsmall[i]=getsum(num[i]-1);
zbig[i]=getsum(maxn-1)-getsum(num[i]);
l+=zsmall[i];
update(num[i]);
}
// for(int i=1;i<=n;i++) cout<<zsmall[i]<<" "; cout<<endl;
// for(int i=1;i<=n;i++) cout<<zbig[i]<<" "; cout<<endl;
memset(tree,0,sizeof(tree));
for(int i=n;i>=1;i--)
{
ysmall[i]=getsum(num[i]-1);
ybig[i]=getsum(maxn-1)-getsum(num[i]);
r+=ysmall[i];
update(num[i]);
}
// for(int i=1;i<=n;i++) cout<<ysmall[i]<<" "; cout<<endl;
// for(int i=1;i<=n;i++) cout<<ybig[i]<<" "; cout<<endl;
// for(int i=1;i<=n;i++) cout<<zsmall[i]+ybig[i]<<" "; cout<<endl;
// for(int i=1;i<=n;i++) cout<<zbig[i]+ysmall[i]<<" "; cout<<endl;
ans=l*r;
ll left=0;
ll right=0;
for(int i=1;i<=n;i++)
{
ans-=(zsmall[i]+ybig[i])*(zbig[i]+ysmall[i]);
}
printf("%lld\n",ans);
}
return 0;
}