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

 

你可能感兴趣的:(sequence)