用树状数组解决求统计问题:hdu2492

     记得暑假的时候看《亚洲区预选赛真题题解》的时候,看到树状数组那道题,只是勉强看懂思路了!树状数组的结节根本就没有掌握。时隔四个月,再回头看这道题,感觉轻松多了!

     对于hdu2492这道题,用树状数组是非常好的选择,代码短,结构简单,不易出错!

     其核心的思路在于:假如有a1 a2 a3 a4 a5 a6 a7 a8 a9这段数据,我们枚举每个点,假如到了a4,那么我们需要知道的是:

          a1 a2 a3中小于a4的有多少?

          a5 a6 a7 8 a9中大于a4的有多少?

     这里的统计就用到的树状数组!

     把代码贴出来吧!

     

 
 
  1. #include<stdio.h> 
  2. #include<string.h> 
  3. #define MM 100000 
  4. #define MN 20000 
  5. int n; 
  6. int a[MN+100],tree[2][MM+100]; 
  7. int left[MN+100],right[MN+100]; 
  8. void init(){ 
  9.  
  10.     memset(tree,0,sizeof(tree)); 
  11.     memset(left,0,sizeof(left)); 
  12.     memset(right,0,sizeof(right)); 
  13. int lowbit(int x){ 
  14.     return x&(-x); 
  15. void insert(int pos,int flag){ 
  16.     while(pos<=MM){ 
  17.             tree[flag][pos]++; 
  18.         pos+=lowbit(pos); 
  19.     } 
  20. int query(int pos,int flag){ 
  21.     int ans=0; 
  22.     while(pos>0){ 
  23.         ans+=tree[flag][pos]; 
  24.         pos-=lowbit(pos); 
  25.     } 
  26.     return ans; 
  27. int main(){ 
  28.     int t,i; 
  29.     scanf("%d",&t); 
  30.     while(t--){ 
  31.         scanf("%d",&n); 
  32.         init(); 
  33.         for(i=1;i<=n;i++){ 
  34.             scanf("%d",&a[i]); 
  35.         } 
  36.         for(i=1;i<=n;i++){ 
  37.             left[i]=query(a[i]-1,0); 
  38.             insert(a[i],0); 
  39.         } 
  40.         for(i=n;i>0;i--){ 
  41.             right[i]=query(a[i]-1,1); 
  42.             insert(a[i],1); 
  43.         } 
  44.         long long ans=0; 
  45.         for(i=1;i<=n;i++){ 
  46.             ans+=(long long)left[i]*(long long)(n-i-right[i])+(long long)(i-left[i]-1)*(long long)right[i]; 
  47.         } 
  48.         printf("%I64d\n",ans); 
  49.     } 
  50.  
  51.     return 0; 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值