您的位置:首页 > 其它

HDU 5792 World is Exploding

2017-04-20 21:16 225 查看


World is Exploding

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

先离散化然后用树状数组预处理

x1[i] i之前比i小的数目

x2[i] i之前比i大的数目

y1[i] i之后比i小的数目

y2[i] i之后比i大的数目

求出总搭配数目然后去重

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <set>
#include <map>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <bitset>
#include <string>
#include <vector>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define maxn 50010
#define ll long long
using namespace std;
int c[maxn], n;
int lowbit(int x)
{
return x & (-x);
}
void  update(int i,  int x)
{
while (i <= n)
{
c[i] = c[i] + x;
i += lowbit(i);
}
}
long long sum(int i)
{
long long  ans = 0;
while (i > 0)
{
ans += c[i];
i -= lowbit(i);
}
return ans;
}
int main()
{
while (scanf("%d", &n) != EOF)
{
long long sumx1 = 0, sumx2 = 0, ans = 0;
int a[maxn], b[maxn], val[maxn];
// x1[i] i之前比i小的数目
// x2[i] i之前比i大的数目
// y1[i] i之后比i小的数目
// y2[i] i之后比i大的数目
int x1[maxn], x2[maxn], y1[maxn], y2[maxn];
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
b[i] = a[i];
}
sort(b + 1, b + n + 1);
int m = unique(b + 1, b + n + 1) - (b + 1); //注意要减(b+1)
for (int i = 1; i <= n; i++)
{
val[i] = lower_bound(b + 1, b + m + 1, a[i]) - b;
}
memset(c, 0, sizeof(c));
for (int i = 1; i <= n; i++)
{
update(val[i], 1);
x1[i] = sum(val[i] - 1);
x2[i] = i - sum(val[i]);
sumx1 += x1[i];
sumx2 += x2[i];
}
memset(c, 0, sizeof(c));
for (int i = n; i >= 1; i--)
{
update(val[i], 1);
y1[i] = sum(val[i] - 1);
y2[i] = n - i + 1 - sum(val[i]);
}
ans = sumx1 * sumx2;
for (int i = 1; i <= n; i++)
{
ans -= ((ll)y1[i] * y2[i]); // a==c
ans -= ((ll)x2[i] * y2[i]); // a==d
ans -= ((ll)x1[i] * y1[i]); // b==c
ans -= ((ll)x1[i] * x2[i]); // b==d
}
printf("%I64d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: