World is Exploding
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 585 Accepted Submission(s): 274
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
Sample Output
Author
ZSTU
Source
2016 Multi-University Training Contest 5
Recommend
wange2014
题意
给出一个数串A
然后问你满足a,b,c,d各不相同且
aAd
的4元组个数
解题思路
如果这个题目是二元组的话
就变成了树状数组水题
那么4元组其实可以拆解为2个二元组
树状数组求解出
rbig,lbig,rsmall,lsmall
分别代表i位置左侧比它大的个数,右侧比它大的个数,左侧比它小的个数,右侧比它小的个数
问题是如果把两个二元组的解乘起来
那么有一些重复计数的
我们发现这些重复的情况有
a=c b=d(这个其实是0个,因为大于小于都是严格的)
a=c b>d(这个枚举a,然后b和d的选择是没有交集的把rbig和rsmall乘起来就可以了)
a
a=d rbig*lbig
b=c rsmall*lsmall
减掉这些多算的就可以了
两个点,一个需要离散化,一个有重复数字
#include
#include
#include
#include
using namespace std;
typedef unsigned long long LL;
const int M=5e4+5;
int nu[M],nu2[M];
LL t1[M];
LL lbig[M],lsmall[M],rbig[M],rsmall[M];
inline int lowbit(int x)
{
return x&(-x);
}
void add(LL t[],int x,int v)
{
for(int i=x;i=1;i--)
{
int tmp=findv(nu[i]);
add(t1,tmp,1);
rsmall[i]=getsum(t1,tmp-1);
rbig[i]=n-i-getsum(t1,tmp)+1;
sumrbig+=rbig[i];
sumrsmall+=rsmall[i];
}
//for(int i=1;i<=n;i++)
// cout<<"i "<