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 代码君
    代码君

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

  • 相关阅读:
    oracle数据库使用PL/sql导入excel数据
    http协议详解之响应报文 3
    http详解之post 2
    http协议详解1
    tomcat配置https协议
    linux服务端导入oracle数据库.sql脚本
    fiddler查看http压缩格式传输的报文
    SurfaceView绘制录音波形图
    android 蓝牙SPP协议通信
    好用的Android屏幕适配
  • 原文地址:https://www.cnblogs.com/usedrosee/p/4179212.html
Copyright © 2011-2022 走看看