zoukankan      html  css  js  c++  java
  • hdu 5147(树状数组)

    Sequence II

    Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 1002    Accepted Submission(s): 408


    Problem Description
    Long long ago, there is a sequence A with length n. All numbers in this sequence is no smaller than 1 and no bigger than n, and all numbers are different in this sequence.
    Please calculate how many quad (a,b,c,d) satisfy:
    1. 1a<b<c<dn
    2. Aa<Ab
    3. Ac<Ad
     
    Input
    The first line contains a single integer T, indicating the number of test cases.
    Each test case begins with a line contains an integer n.
    The next line follows n integers A1,A2,,An.

    [Technical Specification]
    1 <= T <= 100
    1 <= n <= 50000
    1 <= Ai <= n
     
    Output
    For each case output one line contains a integer,the number of quad.
     
    Sample Input
    1 5 1 3 2 4 5
     
    Sample Output
    4
     
    Source
     
    题意:找出一个长度为n的串里面有多少数字满足 Aa<Ab,Ac<Ad,a<b<c<d (a,b,c,d是下标)
    题解:做过这个题之后一看就知道是树状数组统计了,我的想法是对每个 b 进行统计,首先是对b前面的数字进行统计,统计有多少个比它小的,这里可以利用树状数组的逆序模型进行统计。然后对于b后面的数字,我们可以统计有多少对 (c,d),这里的话从n-1对每个数进行统计比它大的有多少,然后如果要统计 b 后面有多少个比它大的数对,那么我们就可以利用保存后缀和的方式存下来就OK,最后里用乘法原理统计即可。l,r数组一定记得开_int64 ,不然会溢出。
    解释一下这里的后缀,比如说 1 2 3 4 5
    先统计 5 ,没有比他大的,所以r[5] = 0
    然后是 4 ,5 比他大,所以 r[4] = 1
    然后是 3 , 4 5比他大,所以 r[3]=2,加上后面已经出现的r[4],r[3]=r[3]+r[4] = 3
    然后是 2 ,r[2]:(2,3)(2,4)(2,5) 加上 (3,4),(3,5),(4,5),所以r[2] = 6
    最后是 1 , r[1]:(1,2)(1,3)(1,4)(1,5),加上r[3] 所以 r[1] = 10
    我们是以 Ab 为基准的,所以每次统计的是 b 之前比比他小的,以及他后面所包含的二元组.所以每次的结果是 L[b]*R[b+1]
    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include <stdlib.h>
    #include<math.h>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    const int N = 50005;
    int n;
    int c[N],a[N];
    LL l[N],r[N];
    int lowbit(int x)
    {
        return x&-x;
    }
    void update(int idx,int v)
    {
        for(int i=idx; i<=n; i+=lowbit(i))
        {
            c[i]+=v;
        }
    }
    int getsum(int idx)
    {
        int sum = 0;
        for(int i=idx; i>0; i-=lowbit(i))
        {
            sum+=c[i];
        }
        return sum;
    }
    int main()
    {
        int tcase;
        scanf("%d",&tcase);
        while(tcase--)
        {
            memset(c,0,sizeof(c));
            memset(l,0,sizeof(l));
            scanf("%d",&n);
            int cnt = 0;
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&a[i]);
                update(a[i],1);
                l[i] = getsum(a[i]-1); ///a[i]之前小于a[i]的数
            }
            memset(c,0,sizeof(c));
            memset(r,0,sizeof(r));
            for(int i=n; i>=1; i--)
            {
                update(a[i],1);
                r[i]=n-i-getsum(a[i]-1);///统计每个数后面比它大的
                r[i]+=r[i+1]; ///记录后缀和
            }
            LL ans = 0;
            for(int i=2;i<n-1;i++){
                ans+=l[i]*r[i+1];
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    [Javascript] property function && Enumeration
    [Javascript]3. Improve you speed! Performance Tips
    [Ember] Wraming up
    [Javascript] How to write a Javascript libarary
    [Regex Expression] Tagline --- {0, } {1,10}
    [Regex Expression] Confirmative -- World bundry
    [Regex Expression] Match mutli-line number, number range
    成都-地点-文创-锦里:锦里
    成都-地点-文创-宽窄巷子:宽窄巷子
    地点-文创-田子坊-上海:田子坊
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5671466.html
Copyright © 2011-2022 走看看