HDU_5792_WorldIsExploding(树状数组&&离散化)

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: abcd,1a<bn,1c<dn,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,A2An.
1n50000
0Ai1e9
 

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
 

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 "<

你可能感兴趣的:(HDU,树状数组,离散化)