zoukankan      html  css  js  c++  java
  • hdu5147 (sequence 2) 树状数组

     1 #include <iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<vector>
     6 #include<map>
     7 using namespace std;
     8 #define INF 0x7fffffff
     9 #define MOD 1000000007
    10 
    11 
    12 #define N 100010
    13 #define MAX 1000100
    14 
    15 int C[MAX], S[MAX], b[N],d[N];
    16 long long f[N];
    17 long long total[N], ans;
    18 int num[N], T, s, t, i, j;
    19 
    20 int Lowbit(int x){
    21     return x&(x^(x-1));
    22 }
    23 
    24 void add(int pos,int num,int *P) {
    25     while(pos <= MAX) {
    26         P[pos] += num;
    27         pos += Lowbit(pos);
    28     }
    29 }
    30 
    31 int Sum(int end,int *P) {
    32     int cnt = 0;
    33     while(end > 0) {
    34         cnt += P[end];
    35         end -= Lowbit(end);
    36     }
    37     return cnt;
    38 }
    39 
    40 void init(){
    41     total[0] = 0;
    42     for(i = 1; i < N; ++i){
    43         total[i] = total[i-1] + i;
    44     }
    45 }
    46 
    47 int main() {
    48     //init();
    49     int t;
    50     cin>>t;
    51 
    52     while(t--) {
    53 
    54         scanf("%d",&T);
    55 
    56         memset(C,0,sizeof(C));
    57         memset(S,0,sizeof(S));
    58         memset(b,0,sizeof b);
    59         memset( d,0,sizeof d);
    60         memset(f,0,sizeof f);
    61         memset(num,0,sizeof num);
    62         //memset(num,0,sizeof(num));
    63         //memset(b,0,sizeof(b));
    64         //ans = 0;
    65         for(j = 0; j < T; j ++) {//因为第一个数前面比它小的数没有,所以j要从0开始
    66             scanf("%d",&num[j]);
    67             add(num[j]+1,1,C);
    68             b[j] = Sum(num[j], C);//Sum(num[j],C)求的就是小于s的个数,j - Sum(num[j],C)就是前j个数中大于num[j]的个数
    69             //printf("%d ",b[j]);
    70         }
    71         //printf("
    ");
    72         //ans = 0;
    73         for(j = T-1; j > -1; --j){//反过来求第j个数右边中大于它的数的个数。
    74             add(num[j]+1 ,1, S);
    75             d[j] =T-1-j-Sum(num[j] ,S);//Sum(num[j],S)求的就是小于num[j]的个数
    76             //b[j] -= Sum(num[j]+1,S) - Sum(num[j],S)-1;
    77             //printf("%d ",b[j]);
    78             //ans += total[b[j]];
    79         }
    80         f[T-1]=0;
    81        for(int j=T-2;j>=0;j--)
    82         f[j]=d[j+1]+f[j+1];
    83        long long int res=0;
    84        for(int j=0;j<T;j++)
    85         res+=b[j]*f[j];
    86        cout<<res<<endl;
    87 
    88     }
    89     return 0;
    90 }
    91 
    92 代码君
    代码君

    理解有问题的话,先看树状数组求逆序数。

  • 相关阅读:
    Coursera公开课-Machine_learing:编程作业4
    C与C艹的内存管理方式
    诡异之--map clear 之后可能导致size != 0的操作
    c++ 四种类型转换机制
    C++ 由虚基类 虚继承 虚函数 到 虚函数表
    dynamic_cast 与 typeid
    Coursera公开课-Machine_learing:编程作业3
    【Leetcode 166】 Fraction to Recurring Decimal
    宏与可变参数
    C语言之内存覆盖
  • 原文地址:https://www.cnblogs.com/usedrosee/p/4179212.html
Copyright © 2011-2022 走看看