news 2026/2/25 13:02:28

P1637 三元上升子序列[线段树维护 + 离散化]

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
P1637 三元上升子序列[线段树维护 + 离散化]

P1637 三元上升子序列

时间限制: 1.00s 内存限制: 128.00MB

复制 Markdown

中文

退出 IDE 模式

题目描述

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

在含有 n 个整数的序列 a1​,a2​,…,an​ 中,三个数被称作thair当且仅当 i<j<k 且 ai​<aj​<ak​。

求一个序列中thair的个数。

输入格式

开始一行一个正整数 n,

以后一行 n 个整数 a1​,a2​,…,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% 的数据 保证 1≤n≤3×104,1≤ai​≤105。

数字范围大于数组范围 防止浪费空间可以开离散化

我们可以用一个桶 然后每次在对应位置上加1 那么当添加了i-1个数字的时候 比第i个数字小的数字就是桶i前面的所有桶的数字之和 这个过程正反均来一遍就可以得到一个数字前面有多少比他小以及后面有多少比他大 最后的答案乘起来即可

离散化后 num[i]就表示 第i个数字的大小 由于离散化 和桶排序 也代表了桶的序号

统计num[i]的情况的时候 就需要算出1~num[i]-1的所有桶的数字和 就是有多少个数字小于他

大于同理

#include <bits/stdc++.h> using namespace std; #define int long long const int N=3e4+5; int n,low[N],up[N],cnt,num[N]; pair<int ,int>a[N]; struct SegmentTree{ int l,r,sum; #define l(x) tree[x].l #define r(x) tree[x].r #define sum(x) tree[x].sum }tree[N<<2]; void pushup(int p){ sum(p)=sum(p<<1)+sum(p<<1|1); } void build(int p,int l,int r){ l(p)=l,r(p)=r; if(l==r){sum(p)=0;return;} int mid=(l+r)>>1; build(p<<1,l,mid); build(p<<1|1,mid+1,r); pushup(p); } void update(int p,int pos){ if(l(p)==r(p)&&l(p)==pos){ sum(p)++; return; } int mid =(l(p)+r(p))>>1; if(pos<=mid)update(p<<1,pos); else update(p<<1|1,pos); pushup(p); } int query(int p,int l,int r){ if(l<=l(p)&&r>=r(p)) return sum(p); int mid =(l(p)+r(p))>>1; int val=0; if(l<=mid)val+=query(p<<1,l,r); if(r>mid)val+=query(p<<1|1,l,r); return val; } signed main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>n; for(int i=1;i<=n;i++)cin>>a[i].first,a[i].second=i; sort(a+1,a+1+n); for(int i=1;i<=n;i++){ if(a[i].first>a[i-1].first)cnt++; num[a[i].second]=cnt; } build(1,1,cnt); for(int i=1;i<=n;i++){ if(num[i]>1)low[i]=query(1,1,num[i]-1); else low[i]=0; update(1,num[i]); } build(1,1,cnt); for(int i=n;i>=1;i--){ if(num[i]<cnt)up[i]=query(1,num[i]+1,cnt); else up[i]=0; update(1,num[i]); } int ans=0; for(int i=1;i<=n;i++){ ans+=low[i]*up[i]; } cout<<ans<<'\n'; return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/25 9:25:06

牛批了,文字转语音神器

有时候在做一些短视频时&#xff0c;需要进行配音。有一些配音软件是收费的&#xff0c;今天给大家介绍一款免费的文字转语音的软件&#xff0c;有需要的小伙伴一定要下载收藏。 Read Aloud 免费的文字转语音软件 这款软件体积非常小巧&#xff0c;大小只有3兆。 软件无需安装…

作者头像 李华
网站建设 2026/2/24 22:05:40

LabVIEW与主流信号发生器接口协议深度剖析

LabVIEW如何“驯服”信号发生器&#xff1f;——从GPIB到PXIe的全接口实战解析你有没有遇到过这样的场景&#xff1a;LabVIEW程序写得行云流水&#xff0c;可一运行就卡在VISA Open那一步&#xff0c;设备就是连不上&#xff1f;或者明明发了:FREQ 1MHz&#xff0c;信号发生器却…

作者头像 李华
网站建设 2026/2/24 9:15:23

Thinkphp-Laravel基于Vue的健身房信息管理系统_q3su4

目录系统概述技术栈核心功能系统优势应用场景项目开发技术介绍PHP核心代码部分展示系统结论源码获取/同行可拿货,招校园代理系统概述 Thinkphp-Laravel基于Vue的健身房信息管理系统是一个结合后端框架&#xff08;ThinkPHP与Laravel&#xff09;和前端框架&#xff08;Vue.js&…

作者头像 李华
网站建设 2026/2/16 0:37:24

从零实现数字信号观测:Proteus示波器使用方法

从零开始玩转数字信号&#xff1a;手把手教你用Proteus示波器看懂电路“心跳”你有没有过这样的经历&#xff1f;写了一段单片机代码&#xff0c;烧进芯片后LED就是不闪&#xff1b;或者搭了个555振荡电路&#xff0c;万用表测电压正常&#xff0c;可信号就是不对劲。这时候要是…

作者头像 李华
网站建设 2026/2/20 19:08:08

Pixhawk使用ArduPilot的固件烧录操作指南

手把手教你给 Pixhawk 刷 ArduPilot 固件&#xff1a;从入门到避坑 你有没有遇到过这样的情况&#xff1f;刚拿到一块崭新的 Pixhawk 飞控&#xff0c;满心期待地插上电脑&#xff0c;打开地面站软件&#xff0c;结果设备不识别、固件刷不进去、进度条卡死……最后只能对着那块…

作者头像 李华
网站建设 2026/2/21 2:18:55

全网最全本科生必用AI论文网站TOP8测评

全网最全本科生必用AI论文网站TOP8测评 2026年本科生必备AI论文网站测评&#xff1a;从功能到体验全面解析 随着人工智能技术的不断进步&#xff0c;越来越多的学术工具被应用于论文写作中。对于本科生而言&#xff0c;如何在有限的时间内高效完成高质量的论文&#xff0c;成为…

作者头像 李华