HDU 5792 World is Exploding

来源:互联网 发布:棋牌游戏数据库 编辑:程序博客网 时间:2024/06/07 06:40

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: 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
42 4 1 341 2 3 4
 

Sample Output
10

先离散化然后用树状数组预处理
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 longusing 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;}


0 0
原创粉丝点击