题目链接:https://www.luogu.org/problemnew/show/P1637

BIT + 离散化。

读题得数据规模需离散化。BIT开不到longint这么大的数组。

对于题目所求的三元上升子序列,我们可以通过枚举1~n作为中间数,记录左边比他小的个数L[i],右边比他大的个数R[i],那么对于第i个中间数就有L[i]*R[i]个子序列。

L,R可以通过树状数组求得。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 3e4 + 10;
int n, m, A[maxn], B[maxn], L[maxn], R[maxn];
class BIT{
public:
int tree[maxn];
void update(int pos, int val)
{
while(pos <= n)
{
tree[pos] += val;
pos += lowbit(pos);
}
}
int query(int pos)
{
int res = 0;
while(pos)
{
res += tree[pos];
pos -= lowbit(pos);
}
return res;
}
private:
int lowbit(int x)
{
return x & -x;
}
}T[2];
int Search(int x)
{
return lower_bound(B + 1, B + 1 + m, x) - B;
}
int main()
{
cin>>n;
for(int i = 1; i <= n; i++)
{
cin>>A[i];
B[i] = A[i];
}
sort(B + 1, B + 1 + n);
m = unique(B + 1, B + 1 + n) - B - 1;
for(int i = 1; i <= n; i++)
A[i] = Search(A[i]);
for(int i = 1; i <= n; i++)
{
T[0].update(A[i], 1);
L[i] = T[0].query(A[i] - 1);
}
for(int i = n; i >= 1; i--)
{
T[1].update(A[i], 1);
R[i] = n - i - T[1].query(A[i]) + 1;
}
long long ans = 0;
for(int i = 2; i < n; i++) ans += L[i] * R[i];
cout<<ans;
return 0;
}

附:

离散化模板:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e4 + 10;
int n, m, A[maxn], B[maxn];
int Search(int x)
{
return lower_bound(B + 1, B + 1 + m, x) - B;
}
int main()
{
cin>>n;
for(int i = 1; i <= n; i++)
{
cin>>A[i];
B[i] = A[i];
}
sort(B + 1, B + 1 + n);
m = unique(B + 1, B + 1 + n) - B - 1;
for(int i = 1; i <= n; i++)
A[i] = Search(A[i]);
for(int i = 1; i <= n; i++) cout<<A[i];
}

【luogu P1637 三元上升子序列】 题解的更多相关文章

  1. Luogu P1637 三元上升子序列【权值线段树】By cellur925

    题目传送门 emmm..不开结构体的线段树真香! 首先我们知道"三元上升子序列"的个数就是对于序列中的每个数,**它左边比他小的数*它右边比他大的数**.但是如何快速求出这两个数? ...

  2. 洛谷P1637 三元上升子序列

    P1637 三元上升子序列 48通过 225提交 题目提供者该用户不存在 标签云端 难度提高+/省选- 时空限制1s / 128MB 提交  讨论  题解 最新讨论更多讨论 为什么超时啊 a的数据比较 ...

  3. P1637 三元上升子序列

    thair 好,这个naive的东西因为只有三元,很好求解.只要把每个数之前小的L[i]与之后大的R[i]求一下即可. 求两次逆序对即可.那么答案便是∑(L[i]*R[i]); 对于更高元的,胡雨菲写 ...

  4. 洛谷p1637 三元上升子序列(树状数组

    题目描述 Erwin最近对一种叫"thair"的东西巨感兴趣... 在含有n个整数的序列a1,a2......an中, 三个数被称作"thair"当且仅当i&l ...

  5. luogu P1126 机器人搬重物 题解

    luogu P1126 机器人搬重物 题解 题目描述 机器人移动学会(\(RMI\))现在正尝试用机器人搬运物品.机器人的形状是一个直径\(1.6\)米的球.在试验阶段,机器人被用于在一个储藏室中搬运 ...

  6. 【Luogu P1637】 三元上升子序列

    对于每个数$a_i$,易得它对答案的贡献为 它左边比它小的数的个数$\times$它右边比它大的数的个数. 可以离散化后再处理也可以使用动态开点的线段树. 我使用了动态开点的线段树,只有需要用到这个节 ...

  7. 【洛谷P1637】三元上升子序列

    题目大意:给定一个长度为 N 的序列,求有多少个三元组满足 \(i<j<k,a_i<a_j<a_k\). 题解:这是一类二维偏序问题,与逆序对问题类似. 对于序列中每个点来说, ...

  8. BZOJ5157 & 洛谷3970:[TJOI2014]上升子序列——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=5157 https://www.luogu.org/problemnew/show/P3970 给定 ...

  9. 【luogu P2491 [SDOI2011]消防】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2491 题外话: OI一共只有三种题--会的题,不会的题,二分题. 题解: step 1 求树的直径,把树的直 ...

随机推荐

  1. java线程池之一:创建线程池的方法

    在Java开发过程中经常需要用到线程,为了减少资源的开销,提高系统性能,Java提供了线程池,即事先创建好线程,如果需要使用从池中取即可,Java中创建线程池有以下的方式, 1.使用ThreadPoo ...

  2. jquery对象里面的context参数

    jquery源码: jQuery = function( selector, context ) { // The jQuery object is actually just the init co ...

  3. Python 起步 多版本共存配置

    上次我选择的是py2.x,如果我要再装一个py3.x呢 我们去设置环境变量,然后去命令行输入python,这里我故意把环境变量放在第一行,貌似换成3.7了 我们把2.7的放在3.7的前面呢?又换回去了 ...

  4. js如何删除json里的值

    思路 第一种方法:通过把json中需要的值取出来,重新生成json对象,这种方法比较笨 第二种方法:通过delete 删除属性,这种方法比较常用,在第三方js库中经常能看到,推荐 举例 1 2 3 4 ...

  5. mysql隔离级别与锁,接口并发响应速度的关系(2)

    innoDB默认隔离级别 mysql> SELECT @@tx_isolation; +-----------------+ | @@tx_isolation | +-------------- ...

  6. SpringMVC(一) 基础知识+入门案例

    SpringMVC基础知识 1.什么是Springmvc 2.springmvc 框架的原理(必须掌握) 前端控制器.处理器映射器.处理器适配器.视图解析器 3.SpringMVC 入门程序 目的:对 ...

  7. python操作json文件

    import json class OperationJson(object): def __init__(self,file_name=None): if file_name: self.file_ ...

  8. Murano简介

    Project Mission The mission for this project is to provide a way to make third-party applications an ...

  9. python学习二(文件与异常)

    Python中使用open BIF与文件交互,与for语句结合使用,一次读取一行 读取文件sketch.txt,文件内容如下: Man: Ah! (taking out his wallet and ...

  10. Unity在Project视图里面显示文件的拓展名

    Unity在Project视图里面显示文件的拓展名 功能脚本如下: using System.IO; using System.Reflection; using UnityEngine; using ...