HDU 5792 World is Exploding

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

按照b来计算答案,看看左边a的数量,以及每一对会产生的数量。

#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<bitset>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define rep(i,j,k) for (int i = j; i <= k; i++)
#define per(i,j,k) for (int i = j; i >= k; i--)
using namespace std;
typedef __int64 LL;
const int low(int x) { return x&-x; }
const double eps = 1e-8;
const int INF = 0x7FFFFFFF;
const int mod = 1e9 + 7;
const int N = 1e5 + 10;
int T, n, m, a[N], b[N];
LL f[2][N], s[N];

LL get(int t, int x)
{
    LL res = 0;
    for (int i = x; i; i -= low(i)) res += f[t][i];
    return res;
}

void insert(int t, int x, LL y)
{
    for (int i = x; i < m; i += low(i)) f[t][i] += y;
}

int main()
{
    //scanf("%d", &T);
    //while (T--)
    while (scanf("%d", &n) != EOF)
    {
        rep(i, 1, n) scanf("%d", &a[i]), b[i] = a[i];
        sort(b + 1, b + n + 1);  m = unique(b + 1, b + n + 1) - b;
        rep(i, 1, n) a[i] = lower_bound(b + 1, b + m, a[i]) - b;
        rep(i, 1, m) f[0][i] = f[1][i] = 0;
        LL ans = 0, sum = 0;
        per(i, n, 1)
        {
            s[i] = get(0, a[i] - 1);
            insert(0, a[i], 1);
        }
        rep(i, 1, n)
        {
            insert(1, a[i], 1);
            s[i] += i - get(1, a[i]);
            sum += s[i];
        }
        sum /= 2;
        rep(i, 1, m) f[0][i] = f[1][i] = 0;
        rep(i, 1, n)
        {
            ans += get(0, a[i] - 1)*(sum - s[i]) - get(1, a[i] - 1);
            insert(0, a[i], 1); insert(1, a[i], s[i]);
        }
        printf("%lld\n", ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值