盛夏的果实 发表于 2021-7-16 20:14:40

hdu 5792 World is Exploding 树状数组

World is Exploding

题目连接:
http://acm.hdu.edu.cn/showproblem.php?pid=5792

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

Hint

题意
给你n个数,问你有多少个四元组,满足a!=b,b!=c,c!=d,a!=d,a!=c,b!=d,且A<A,a<b,A>A,c<d的关系的。

题解:
考虑容斥,我们知道(a,b)的对数,(c,d)的对数,两个乘起来,再减去不合法的就好了。

不合法的,显然就是长度为3的哪些重复计算的,只要减去就好了。

维护l表示前面有多少个比他小,l1前面有多少个比他大

r后面有多少个比他小,r1有多少个比他大

然后莽一波容斥。

代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e4+7;
int d,n,a,l,r,l1,r1;;
int lowbit(int x){
    return x&(-x);
}
void update(int x,int v){
    for(int i=x;i<maxn;i+=lowbit(i))
      d+=v;
}
int get(int x){
    int ans = 0;
    for(int i=x;i;i-=lowbit(i))
      ans+=d;
    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);
            V.push_back(a);
      }
      sort(V.begin(),V.end());
      V.erase(unique(V.begin(),V.end()),V.end());
      for(int i=0;i<V.size();i++)
            H]=i+1;
      for(int i=1;i<=n;i++)a=H];

      long long ans1=0,ans2=0,ans3=0;
      for(int i=1;i<=n;i++){
            l=get(a-1);
            l1=get(maxn-1)-get(a);
            update(a,1);
      }
      memset(d,0,sizeof(d));
      for(int i=n;i>=1;i--){
            r=get(a-1);
            r1=get(maxn-1)-get(a);
            update(a,1);
      }
      for(int i=1;i<=n;i++){
            ans3+=1ll*l*r;
            ans3+=1ll*l1*r1;
            ans3+=1ll*l*l1;
            ans3+=1ll*r*r1;
            ans1+=l,ans2+=r;
      }
      cout<<ans1*ans2-ans3<<endl;
    }
}

文档来源:51CTO技术博客https://blog.51cto.com/u_15303184/3108585
页: [1]
查看完整版本: hdu 5792 World is Exploding 树状数组