• HDU 5792 World is Exploding(树状数组+离散化)


    http://acm.split.hdu.edu.cn/showproblem.php?pid=5792

    题意:

    思路:

    lmin[i]:表示左边比第i个数小的个数。

    lmax[i]:表示左边比第i个数大的个数。

    rmin[i]:表示右边比第i个数小的个数。

    rmax[i]:表示右边比第i个数大的个数。

    这些都是可以用树状数组计算出来的,把所有的lmin加起来就是所有(a,b)对的个数,所有lmax加起来就是所有(c,d)对的个数,两者相乘就是所有情况之和了。但是需要注意的是,在这些情况中还存在a=c,a=d,b=c,b=d这四种不符合题意的,需要把这些给减掉。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<vector>
     6 #include<stack>
     7 #include<queue>
     8 #include<cmath>
     9 #include<map>
    10 #include<set>
    11 using namespace std;
    12 typedef long long ll;
    13 typedef pair<int,int> pll;
    14 const int INF = 0x3f3f3f3f;
    15 const int maxn = 50000+5;
    16 
    17 int n;
    18 int a[maxn],b[maxn],c[maxn];
    19 int lmin[maxn],lmax[maxn],rmin[maxn],rmax[maxn];
    20 
    21 int lowbit(int x)
    22 {
    23     return x&-x;
    24 }
    25 
    26 int get_sum(int x)
    27 {
    28     int ret = 0;
    29     while(x>0)
    30     {
    31         ret+=c[x];
    32         x-=lowbit(x);
    33     }
    34     return ret;
    35 }
    36 
    37 void add(int x)
    38 {
    39     while(x<=n)
    40     {
    41         c[x]+=1;
    42         x+=lowbit(x);
    43     }
    44 }
    45 
    46 int main()
    47 {
    48     //freopen("in.txt","r",stdin);
    49     while(~scanf("%d",&n))
    50     {
    51         for(int i=1;i<=n;i++)
    52         {
    53             scanf("%d",&a[i]);
    54             b[i]=a[i];
    55         }
    56         sort(b+1,b+n+1);
    57         int num=unique(b+1,b+n+1)-(b+1);
    58         for(int i=1;i<=n;i++)
    59             a[i]=lower_bound(b+1,b+num+1,a[i])-(b+1)+1;
    60 
    61         ll suml=0,sumr=0;
    62         memset(c,0,sizeof(c));
    63         for(int i=1;i<=n;i++)
    64         {
    65             lmin[i]=get_sum(a[i]-1);
    66             lmax[i]=get_sum(n)-get_sum(a[i]);
    67             add(a[i]);
    68             suml+=lmin[i];
    69             sumr+=lmax[i];
    70         }
    71         memset(c,0,sizeof(c));
    72         for(int i=n;i>=1;i--)
    73         {
    74             rmin[i]=get_sum(a[i]-1);
    75             rmax[i]=get_sum(n)-get_sum(a[i]);
    76             add(a[i]);
    77         }
    78 
    79         ll ans=suml*sumr;
    80 
    81         for(int i=1;i<=n;i++)
    82         {
    83             ans-=(ll)rmin[i]*rmax[i];//a==c==a[i]
    84             ans-=(ll)lmin[i]*lmax[i];//b==d==a[i]
    85             ans-=(ll)lmin[i]*rmin[i];//b==c==a[i]
    86             ans-=(ll)lmax[i]*rmax[i];//a==d==a[i]
    87         }
    88         printf("%lld
    ",ans);
    89     }
    90     return 0;
    91 }
  • 相关阅读:
    【SQL触发器】类型 FOR 、AFTER、 Instead of到底是什么鬼
    Oracle两种临时表的创建与使用详解
    oracle 临时表(事务级、会话级)
    oracle存储过程游标的使用(批号分摊)
    delphi FastReport快速入门
    Vue 表情包输入组件的实现代码
    一个基于 JavaScript 的开源可视化图表库
    浅淡Webservice、WSDL三种服务访问的方式(附案例)
    记录一下遇到的问题 java将json数据解析为sql语句
    Oracle词汇表(事务表(transaction table)”)
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7665826.html
Copyright © 2020-2023  润新知