• 洛谷 P1637 三元上升子序列


    题目描述

    Erwin最近对一种叫"thair"的东西巨感兴趣。。。

    在含有n个整数的序列a1,a2......an中,

    三个数被称作"thair"当且仅当i<j<k且ai<aj<ak

    求一个序列中"thair"的个数。

    输入格式

    开始一个正整数n,

    以后n个数a1~an。

    输出格式

    "thair"的个数

    输入输出样例

    输入 #1
    4
    2 1 3 4
    输出 #1
    2
    输入 #2
    5
    1 2 2 3 4
    输出 #2
    7

    说明/提示

    对样例2的说明:

    7个"thair"分别是

    1 2 3 1 2 4 1 2 3 1 2 4 1 3 4 2 3 4 2 3 4 约定 30%的数据n<=100

    60%的数据n<=2000

    100%的数据n<=30000

    大数据随机生成

    0<=a[i]<=maxlongint

    思路:我做完这题后,竟然发现没大有和我做法一样的。。。。还是简要说明一下吧。。。其实这个题和求正序对很相似,只不过需要稍微修改一下而已,维护两棵树状数组,第一棵维护的就是求正序对时的每个数的出现次数,第二棵维护以该数为结尾的正序对的个数,我们不难看出,以一个数为结尾的三元上升序列的个数就等于在该数前面的所有比该数小的数为结尾的正序对个数的总和,我们依据这个条件,和正序对求和类似的方法求出答案即可。

    PS:其实我的做法好像是树套树???

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N = 3e4 + 5;
     7 typedef long long ll;
     8 ll read()
     9 {
    10     ll ret = 0;
    11     char ch = getchar();
    12     while(ch < '0' || ch > '9') ch = getchar();
    13     while(ch >= '0' && ch <= '9')
    14     {ret = ret * 10 + ch - '0'; ch = getchar();}
    15     return ret;
    16 }
    17 int n;
    18 #define lowbit(x) x & -x;
    19 ll atr[N][2];
    20 void modify_add(int pos, ll v, int id)
    21 {
    22     while(pos <= n)
    23     {
    24         atr[pos][id] += v;
    25         pos += lowbit(pos);
    26     }
    27 }
    28 ll ask_presum(int pos, int id)
    29 {
    30     ll ret = 0;
    31     while(pos)
    32     {
    33         ret += atr[pos][id];
    34         pos -= lowbit(pos);
    35     }
    36     return ret;
    37 }
    38 ll f[N], lsh[N];
    39 int main()
    40 {
    41     scanf("%d", &n);
    42     for(int i = 1; i <= n; i ++) f[i] = read(), lsh[i] = f[i];
    43     sort(lsh + 1, lsh + 1 + n);
    44     int sup = unique(lsh + 1, lsh + 1 + n) - (lsh + 1);
    45     ll ans = 0;
    46     for(int i = 1; i <= n; i ++)
    47     {
    48         int pos = lower_bound(lsh + 1, lsh + 1 + sup, f[i]) - lsh;
    49         modify_add(pos, 1, 0);
    50         modify_add(pos, ask_presum(pos - 1, 0), 1);
    51         ans += ask_presum(pos - 1, 1);
    52     }
    53     printf("%lld
    ", ans);
    54     return 0;
    55 }
  • 相关阅读:
    前端开发聚合
    6. webRTC
    14.移动端图片浏览组件 react-wx-images-viewer
    windows下怎样使用md命令一次建立多级子目录
    mysql打印输出转csv格式
    Java Stream简介, 流的基本概念
    Linux使用Shell脚本实现ftp的自动上传下载
    在Linux中设置UMASK值
    SFTP+OpenSSH+ChrootDirectory设置
    导出php5.4支持的数组格式,即以[]为标识符而不是以array()标识
  • 原文地址:https://www.cnblogs.com/loi-frank/p/11751675.html
Copyright © 2020-2023  润新知