hdu 5147 Sequence II

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

 题意:问有多少个这样的四元组(a,b,c,d),满足条件是 1<=a<b<c<d; Aa<Ab; Ac<Ad;

思路:用树状数组求,从右向左求在这个数之前形成多少个逆序数对记录在r数组里面,然后在从左向右求出在输入这个数之前形成多少个逆序数对存在l数组里面,然后枚举b就行;

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define maxn 50001
 5 #define ll long long
 6 using namespace std;
 7 
 8 int t;
 9 int n;
10 int a[maxn];
11 int c[maxn];
12 ll l[maxn],r[maxn],sum[maxn];
13 
14 int lowbit(int x)
15 {
16     return x&-x;
17 }
18 
19 void insert(int x,int v)
20 {
21     while(x<maxn)
22     {
23         c[x]+=v;
24         x+=lowbit(x);
25     }
26 }
27 
28 ll getsum(int x)
29 {
30     ll ans=0;
31     while(x>0)
32     {
33         ans+=c[x];
34         x-=lowbit(x);
35     }
36     return ans;
37 }
38 
39 int main()
40 {
41     scanf("%d",&t);
42     while(t--)
43     {
44         memset(sum,0,sizeof(sum));
45         memset(a,0,sizeof(a));
46         scanf("%d",&n);
47         for(int i=1; i<=n; i++)
48         {
49             scanf("%d",&a[i]);
50         }
51         memset(c,0,sizeof(c));
52         sum[n+1]=0;
53         for(int i=n; i>=1; i--)
54         {
55             r[i]=getsum(n)-getsum(a[i]);
56             insert(a[i],1);
57             sum[i]=sum[i+1]+r[i];
58         }
59         memset(c,0,sizeof(c));
60         for(int i=1; i<=n; i++)
61         {
62             l[i]=getsum(a[i]-1);
63             insert(a[i],1);
64         }
65         ll ans=0;
66         for(int i=2; i<=n; i++)
67         {
68             ans+=(l[i]*sum[i+1]);
69         }
70         printf("%lld\n",ans);
71     }
72     return 0;
73 }
View Code

 

posted @ 2015-01-02 19:29  null1019  阅读(162)  评论(0编辑  收藏  举报