Hdu 5792 World is Exploding

来源:互联网 发布:工程造价软件广联达 编辑:程序博客网 时间:2024/05/29 17:34

时间限制:1S / 空间限制:256MB

【在线测试提交传送门】

【问题描述】

    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.    给定一个长度为n的整数序列,统计有多少个四重元素(a,b,c,d)满足条件:    a≠b≠c≠d,    1≤a<b≤n,  1≤c<d≤n,  Aa<Ab,  Ac>Ad.

【输入格式】

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.输入包含多组测试数据,对于每组测试数据:第一行,一个整数n1≤n≤50000,表示序列元素的个数;接下来n行,每行n个正是,表示A1,A2⋯An。0≤Ai≤1e9

【输出格式】

For each test case,output a line contains an integer.对于每个测试事情,输出一行一个整数。

【输入样例1】

42 4 1 341 2 3 4

【输出样例1】

10

【题目来源】

2016 Multi-University Training Contest 5

【解题思路】

考虑容斥,我们知道(a,b)的对数,(c,d)的对数,两个乘起来,再减去不合法的就好了。
不合法的,显然就是长度为3的哪些重复计算的,只要减去就好了。
维护l[i]表示前面有多少个比他小,l1[i]前面有多少个比他大,
r[i]后面有多少个比他小,r1[i]有多少个比他大,然后容斥计算。

【参考代码】

#include<bits/stdc++.h>using namespace std;const int maxn = 5e4+7;int d[maxn],n,a[maxn],l[maxn],r[maxn],l1[maxn],r1[maxn];;int lowbit(int x){    return x&(-x);}void update(int x,int v){    for(int i=x;i<maxn;i+=lowbit(i))        d[i]+=v;}int get(int x){    int ans = 0;    for(int i=x;i;i-=lowbit(i))        ans+=d[i];    return ans;}map<int,int>H;vector<int> V;int main(){    while(scanf("%d",&n)!=EOF){        memset(l1,0,sizeof(l1));        memset(r1,0,sizeof(r1));        memset(l,0,sizeof(l));        memset(r,0,sizeof(r));        memset(d,0,sizeof(d));        V.clear();H.clear();        for(int i=1;i<=n;i++)        {            scanf("%d",&a[i]);            V.push_back(a[i]);        }        sort(V.begin(),V.end());        V.erase(unique(V.begin(),V.end()),V.end());        for(int i=0;i<V.size();i++)            H[V[i]]=i+1;        for(int i=1;i<=n;i++)a[i]=H[a[i]];        long long ans1=0,ans2=0,ans3=0;        for(int i=1;i<=n;i++){            l[i]=get(a[i]-1);            l1[i]=get(maxn-1)-get(a[i]);            update(a[i],1);        }        memset(d,0,sizeof(d));        for(int i=n;i>=1;i--){            r[i]=get(a[i]-1);            r1[i]=get(maxn-1)-get(a[i]);            update(a[i],1);        }        for(int i=1;i<=n;i++){            ans3+=1ll*l[i]*r[i];            ans3+=1ll*l1[i]*r1[i];            ans3+=1ll*l[i]*l1[i];            ans3+=1ll*r[i]*r1[i];            ans1+=l[i],ans2+=r[i];        }        cout<<ans1*ans2-ans3<<endl;    }}
原创粉丝点击