• [Vijos 1768] 顺序对的值


    顺序对的值

    描述

    给定一个序列a,a中任意两个元素都不等。如果i<j,且a[i]<a[j],则我们称a[i],a[j]为一个顺序对,这个顺序对的值是指a[i+1],a[i+2]…….a[j-1]中比a[i]大,且比a[j]小的数的个数。求一个序列中所有顺序对的值的和。

    格式

    输入格式

    第一行一个数n,表示序列a中元素的个数。

    第二行n个数,第i个数表示a[i]。

    输出格式

    输出一个数,序列a中所有顺序对的值的和。

    样例1

    样例输入1

    5
    1 5 3 4 2

    样例输出1

    1

    限制

    每个测试点2s。

    提示

    对于100%的数据,2<=n<=5000,a[i]<=10^9。

    题意

    求下式的值:

    [sum _{j=1} ^n sum _{i=1}^{j-1} sum _{k=i+1,a[i]<a[k]<a[j]}^{j-1}1]

    题解

    一眼离散化思博题OwO...

    每个数对于排在后面且大于它的数的所得到的答案的贡献等于排在它前面且小于它的数的个数.

    所以考虑开两个能够快速维护前缀和的数据结构, 这样扫描一遍就可以解决.

    两个数据结构一个用于计算贡献一个用于计算最终答案. 

    每次扫描到一个数之后在计算最终答案的结构中查询前缀和并累计到最终答案, 然后在计算贡献的结构中查询前缀和并向计算最终答案的结构中累加. 最后在计算贡献的结构中累加上这个数产生的贡献.

    参考代码

    GitHub

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <iostream>
     5 #include <algorithm>
     6 
     7 const int MAXN=300010;
     8 
     9 #define int long long
    10 
    11 int n;
    12 int* ed;
    13 int a[MAXN];
    14 int d[MAXN];
    15 long long c[MAXN];
    16 long long l[MAXN];
    17 
    18 int Pos(int);
    19 int LowBit(int);
    20 long long Query(long long*,int);
    21 void Add(long long*,int,long long);
    22 
    23 signed main(){
    24     int ans=0;
    25     scanf("%lld",&n);
    26     for(int i=1;i<=n;i++){
    27         scanf("%lld",a+i);
    28         d[i]=a[i];
    29     }
    30     std::sort(d+1,d+1+n);
    31     ed=std::unique(d+1,d+1+n);
    32     for(int i=1;i<=n;i++){
    33         int k=Pos(a[i]);
    34         ans+=Query(c,k);
    35         Add(c,k,Query(l,k));
    36         Add(l,k,1);
    37     }
    38     printf("%lld
    ",ans);
    39     return 0;
    40 }
    41 
    42 inline int Pos(int x){
    43     return std::lower_bound(d+1,ed,x)-d;
    44 }
    45 
    46 inline void Add(long long* c,int x,long long d){
    47     while(x<=n){
    48         c[x]+=d;
    49         x+=LowBit(x);
    50     }
    51 }
    52 
    53 inline long long Query(long long* c,int x){
    54     long long ans=0;
    55     while(x>0){
    56         ans+=c[x];
    57         x-=LowBit(x);
    58     }
    59     return ans;
    60 }
    61 
    62 inline int LowBit(int x){
    63     return x&-x;
    64 }
    Backup

  • 相关阅读:
    通过盘古分词自定义规则功能实现软件版本号的提取
    Js event事件在IE、FF兼容性问题
    Android动画效果 translate、scale、alpha、rotate 切换Activity动画 控件位置调整
    iPhone代码片段收集(持续更新)
    Activity之间的相互调用与传递参数
    android如何拍照以及返回拍的图片(经过验证的实际例子)
    Android API :SMS短信服务处理和获取联系人
    实现Android的消息通知栏
    iPhone开发 调用摄像头进行拍照等操作
    Android模拟 HTTP multipart/formdata 请求协议信息实现图片上传
  • 原文地址:https://www.cnblogs.com/rvalue/p/7325373.html
Copyright © 2020-2023  润新知