【HDU 4000】 树状数组

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

题目大意:给出n个数,求(x<z<y)的次数 。(x,y,z一次先后出现)

解题思路:

题目数据量很大,暴力肯定不行的。

设现在出现的位置为x,后面比它大的数有s个。s个选两个(y,z)有s*(s-1)/2种。此时yz无序。

然后按题目要求x<z<y,所以还要把x<y<z除掉。

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 const int maxn=100005;
 8 const int mod=100000007;
 9 int bit[maxn];
10 int  n;
11 
12 int lowbit(int x)
13 {
14     return x&(-x);
15 }
16 
17 void add(int x, int val)
18 {
19     while(x<=n)
20     {
21         bit[x]+=val;
22         x+=lowbit(x);
23     }
24 }
25 
26 int sum(int x)
27 {
28     int cnt=0;
29     while(x>0)
30     {
31         cnt+=bit[x];
32         x-=lowbit(x);
33     }
34     return cnt;
35 }
36 
37 int main()
38 {
39     int  T, tcase=0, tmp1, tmp2, a;
40     cin >> T;
41     while(T--)
42     {
43         cin >> n;
44         __int64 ans=0;
45         memset(bit,0,sizeof(bit));
46         for(int i=1; i<=n; i++)
47         {
48             scanf("%d",&a);
49             add(a,1);
50             tmp1=sum(a-1);     //a前面比a小的数的个数
51             tmp2=n-a-(i-tmp1-1);  //a后面比a大的数的个数
52             ans-=tmp1*tmp2;    //减去x<y<z这种情况
53             if(tmp2>=2)
54                ans+=tmp2*(tmp2-1)/2;  
55         }
56         printf("Case #%d: %d\n",++tcase,ans%mod);
57     }
58     return 0;
59 }

 

原文地址:https://www.cnblogs.com/kane0526/p/2759656.html