HDU 5792 World is Exploding(树状数组+离散化)

http://acm.split.hdu.edu.cn/showproblem.php?pid=5792

题意:

思路:

lmin[i]:表示左边比第i个数小的个数。

lmax[i]:表示左边比第i个数大的个数。

rmin[i]:表示右边比第i个数小的个数。

rmax[i]:表示右边比第i个数大的个数。

这些都是可以用树状数组计算出来的,把所有的lmin加起来就是所有(a,b)对的个数,所有lmax加起来就是所有(c,d)对的个数,两者相乘就是所有情况之和了。但是需要注意的是,在这些情况中还存在a=c,a=d,b=c,b=d这四种不符合题意的,需要把这些给减掉。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<vector>
 6 #include<stack>
 7 #include<queue>
 8 #include<cmath>
 9 #include<map>
10 #include<set>
11 using namespace std;
12 typedef long long ll;
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const int maxn = 50000+5;
16 
17 int n;
18 int a[maxn],b[maxn],c[maxn];
19 int lmin[maxn],lmax[maxn],rmin[maxn],rmax[maxn];
20 
21 int lowbit(int x)
22 {
23     return x&-x;
24 }
25 
26 int get_sum(int x)
27 {
28     int ret = 0;
29     while(x>0)
30     {
31         ret+=c[x];
32         x-=lowbit(x);
33     }
34     return ret;
35 }
36 
37 void add(int x)
38 {
39     while(x<=n)
40     {
41         c[x]+=1;
42         x+=lowbit(x);
43     }
44 }
45 
46 int main()
47 {
48     //freopen("in.txt","r",stdin);
49     while(~scanf("%d",&n))
50     {
51         for(int i=1;i<=n;i++)
52         {
53             scanf("%d",&a[i]);
54             b[i]=a[i];
55         }
56         sort(b+1,b+n+1);
57         int num=unique(b+1,b+n+1)-(b+1);
58         for(int i=1;i<=n;i++)
59             a[i]=lower_bound(b+1,b+num+1,a[i])-(b+1)+1;
60 
61         ll suml=0,sumr=0;
62         memset(c,0,sizeof(c));
63         for(int i=1;i<=n;i++)
64         {
65             lmin[i]=get_sum(a[i]-1);
66             lmax[i]=get_sum(n)-get_sum(a[i]);
67             add(a[i]);
68             suml+=lmin[i];
69             sumr+=lmax[i];
70         }
71         memset(c,0,sizeof(c));
72         for(int i=n;i>=1;i--)
73         {
74             rmin[i]=get_sum(a[i]-1);
75             rmax[i]=get_sum(n)-get_sum(a[i]);
76             add(a[i]);
77         }
78 
79         ll ans=suml*sumr;
80 
81         for(int i=1;i<=n;i++)
82         {
83             ans-=(ll)rmin[i]*rmax[i];//a==c==a[i]
84             ans-=(ll)lmin[i]*lmax[i];//b==d==a[i]
85             ans-=(ll)lmin[i]*rmin[i];//b==c==a[i]
86             ans-=(ll)lmax[i]*rmax[i];//a==d==a[i]
87         }
88         printf("%lld
",ans);
89     }
90     return 0;
91 }
原文地址:https://www.cnblogs.com/zyb993963526/p/7665826.html