hdu5147----Sequence II

Sequence II

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 38    Accepted Submission(s): 18


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. 1a<b<c<dn
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:   5149  5148  5145  5144  5143 
 

我用2个树状数组来记录第i个元素之前比他小的元素sum[i],第i个元素之后比他大的元素以及区间[i+1, n]里符合题意的二元组ar[i + 1]
然后枚举第二个点, 每个点可以得到sum[i] * ar[i +1], 它们的和就是答案

/*************************************************************************
    > File Name: B.cpp
    > Author: ALex
    > Mail: 405045132@qq.com
    > Created Time: 2014年12月20日 星期六 18时39分53秒
 ************************************************************************/

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int N = 50010;
__int64 sum[N];
__int64 sum2[N];
__int64 ar[N], ar2[N];
int tree[N];
int tree2[N];
int arr[N];
int n;

int lowbit(int x)
{
    return x & (-x);
}

void add(int x)
{
    for (int i = x; i <= n; i += lowbit(i))
    {
        tree[i]++;
    }
}

void add2(int x)
{
    for (int i = x; i <= n; i += lowbit(i))
    {
        tree2[i]++;
    }
}

int get(int x)
{
    int ans = 0;
    for (int i = x; i; i -= lowbit(i))
    {
        ans += tree[i];
    }
    return ans;
}

int get2(int x)
{
    int ans = 0;
    for (int i = x; i; i -= lowbit(i))
    {
        ans += tree2[i];
    }
    return ans;
}

int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        memset (ar, 0, sizeof(ar));
        memset (ar2, 0, sizeof(ar2));
        memset (tree2, 0, sizeof(tree2));
        memset (tree, 0, sizeof(tree));
        memset (sum2, 0, sizeof(sum2));
        memset (sum, 0, sizeof(sum));
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
        {
            scanf("%d", &arr[i]);
        }
        for (int i = n; i >= 1; i--)
        {
            add(arr[i]);
            sum[i] = (n - i + 1 - get(arr[i]));
            ar[i] = ar[i + 1] + sum[i];
        }
        for (int i = 1; i <= n; i++)
        {
            sum2[i]  = (get2(arr[i]));
            add2(arr[i]);
            ar2[i] = ar2[i - 1] + sum[i];
        }
        __int64 ans = 0;
        for (int i = 1; i <= n; i++)
        {
            ans += (ar[i + 1] * sum2[i]);
        }
        printf("%I64d\n", ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值