CSDN同步

原题链接

简要题意:

给定一个 \(1\) ~ \(n\) 的排列,求以 \(b\) 为中位数的 连续子序列且长度为奇数 的个数。

显然这段序列包含 \(b\).

中位数的定义:排序后在最中间的数。

算法一

对于 \(30 \%\) 的数据,\(n \leq 100\).

由于这段序列一定包含 \(b\),那么我们可以枚举区间 \([i,j]\) 包含 \(b\)(有类似于双指针),然后单独取出 \([i,j]\) 这段进行排序,暴力判断即可。

时间复杂度:\(O(n^3 \log n)\).

实际得分:\(30pts\).

算法二

对于 \(60 \%\) 的数据,\(n \leq 1000\).

显然我们不需要每次都把 \([i,j]\) 这段取出,可以一次次扩展。

比方说枚举 \(i\) (从 \(d\) 到 \(1\),\(d\) 是 \(b\) 的位置),然后枚举 \(j\) 从 \(d\) 到 \(n\). 对于每个 \(j\),只需在原来数组的基础上添上一个 \(a_j\) 即可;如果 \(j=n\) 的话,添加之后要把数组清空。

那么每次只需要插入一个数的话,我们可以用 插入排序,因为已经排序的是有序的,因为插入的位置可以用二分算出。插入操作我们不用数组维护,用 \(\text{vector}\) 维护会方便很多。

时间复杂度:\(O(n^2 \log n)\).

实际得分:\(60pts\).

算法三

对于 \(60 \%\) 的数据,\(n \leq 1000\).

抛开排序过程,我们想:因为排列的性质,不存在重复数。所以,一个连续序列的中位数为 \(b\) 当且仅当比 \(b\) 大的数的个数和比 \(b\) 小的数的个数相等。 那么,对于 \(d\) 的左边,线性 \(\text{dp}\) ,用 \(f_i\) 表示 \(i\) ~ \(d\) 比 \(i\) 大的数的个数,\(g_i\) 是小的,同理 \(d\) 的右边也推一遍。

那么,我们枚举左右端点 \(i,j\) 只需要 \(O(1)\) 判断即可。即 \(f_i + g_i = f_j + g_j\).

时间复杂度:\(O(n^2)\).

实际得分:\(60pts\).

算法四

对于 \(60 \%\) 的数据,\(n \leq 1000\).

从算法三的 \(\text{dp}\) 上入手,我们发现,\(f_i + g_i = f_j + g_j\) 等价于 \(f_i - f_j = g_i - g_j\). 所以我们只需要算出 比 \(b\) 大的数的个数与比 \(b\) 小的数的个数之差 重新作为 \(f\) 数组的状态,然后枚举端点即可。

时间复杂度:\(O(n^2)\).

实际得分:\(60pts\).

算法五

对于 \(100 \%\) 的数据,\(n \leq 10^5\).

从算法四上再优化一下,其实对于固定的一个左端点 \(i\),我们只需要算出有多少个 \(j \geq d\) 且 \(f_i = f_j\) 即可。

也就是说,我们需要维护 区间查询相等个数

智商不够,数据结构来凑。所以这个查询我们可以用 \(\text{Treap}\) 或者 \(\text{Splay}\) 来实现。(随便用个平衡树板子都能实现的)

时间复杂度:\(O(n \log n)\).

实际得分:\(100pts\).

算法六

对于 \(100 \%\) 的数据,\(n \leq 10^5\).

从算法五上入手,你发现 区间查询相等个数 是静态查询,不需要修改。那你可以用 权值线段树(主席树) 解决本题。

时间复杂度:\(O(n \log n)\).

实际得分:\(100pts\).

算法七

对于 \(100 \%\) 的数据,\(n \leq 10^5\).

在算法六的基础上,你发现不仅是静态,而且是固定的一个区间 \([d,n]\). 那么我们不需要用 权值线段树(可以理解为 \(n\) 棵线段树),只需要 \(1\) 棵线段树即可。

时间复杂度:\(O(n \log n)\).

实际得分:\(100pts\).

算法八

对于 \(100 \%\) 的数据,\(n \leq 10^5\).

如果你的程序在算法七止步不前,只能说明你是个天才,离最后的成功只差几步了。

固定区间维护静态相等个数,听上去很高大上啊,其实不就是个 \(\text{map}\) 吗?

某同学:我还能 %$#^%*(%&))

嗯,改成 \(\text{map}\) 之后感觉简单多了,是不是?然后我们直接省去 \(f\) 数组,直接存入 \(\text{map}\).

时间复杂度:\(O(n \log n)\).

实际得分:\(100pts\).

//为了看起来清晰 , 用了嵌套三目运算符
// q[tot+=((a[i]>b)?1:(a[i]<b)?-1:0)]++; 其实相当于这几句:
// if(a[i]>b) tot++;
// if(a[i]<b) tot--;
// q[tot]++;
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std; typedef long long ll;
const int N=1e5+1; inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;} int n,b,wz,a[N];
int tot,sum; ll ans=0;
map<int,int> q; int main(){
n=read(),b=read();
for(int i=1;i<=n;i++) a[i]=read(),wz=(a[i]==b)?i:wz;
for(int i=wz;i<=n;i++) q[tot+=((a[i]>b)?1:(a[i]<b)?-1:0)]++;
for(int i=wz;i>=1;i--) ans+=q[0-(sum+=(a[i]>b)?1:((a[i]<b)?-1:0))];
printf("%lld\n",ans);
return 0;
}

算法九

对于 \(200 \%\) 的数据,\(n \leq 10^7\).

(实际上是本人的一个加强)

算法八的基础上,我们可以尝试拿掉这个 \(\log\).

但是你很快发现下标虽然不超过 \(10^7\),但是会有负数,可能有 \(-10^7\).

显然,哈希处理负下标 是这题的最终正解。

把每个下标都加上 \(n\),解决负下标之后 \(O(1)\) 查询,拿掉 \(\text{map}\) 还解决了 \(\log\).

时间复杂度:\(O(n)\).

实际得分:\(200pts\).

P1627 [CQOI2009]中位数 题解的更多相关文章

  1. 洛谷 P1627 [CQOI2009]中位数 解题报告

    P1627 [CQOI2009]中位数 题目描述 给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数是指把所有元素从小到大排列后,位于中间的数. 输入输出格式 输入格式 ...

  2. 洛谷——P1627 [CQOI2009]中位数

    P1627 [CQOI2009]中位数 给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数是指把所有元素从小到大排列后,位于中间的数. 中位数的题目有关统计的话,可以转 ...

  3. luogu P1627 [CQOI2009]中位数

    传送门 要求有多少个长度为奇数的区间满足某个数为区间中位数 这样的区间,大于中位数的数个数 等于 小于中位数的数个数 用类似于前缀和的方法,设\(X_i\)为\(i\)和数\(b\)形成的区间内,大于 ...

  4. p1627 [CQOI2009]中位数

    传送门 分析 https://www.luogu.org/blog/user43145/solution-p1627 代码 #include<iostream> #include<c ...

  5. 【BZOJ1303】[CQOI2009]中位数图(模拟)

    [BZOJ1303][CQOI2009]中位数图(模拟) 题面 BZOJ 洛谷 题解 把大于\(b\)的数设为\(1\),小于\(b\)的数设为\(-1\).显然询问就是有多少个横跨了\(b\)这个数 ...

  6. bzoj 1303: [CQOI2009]中位数图 数学

    1303: [CQOI2009]中位数图 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/ ...

  7. BZOJ 1303 CQOI2009 中位数图 水题

    1303: [CQOI2009]中位数图 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2340  Solved: 1464[Submit][Statu ...

  8. BZOJ 1303: [CQOI2009]中位数图【前缀和】

    1303: [CQOI2009]中位数图 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2737  Solved: 1698[Submit][Statu ...

  9. Luogu1627 [CQOI2009]中位数

    Luogu1627 [CQOI2009]中位数 给出一个 \(n\) 的排列,统计该排列有多少个长度为奇数的连续子序列的中位数是 \(k\) \(n\leq10^5\) \(trick\) :因为不需 ...

随机推荐

  1. [NodeJS] async 和 await 的本质

    ​    绝大多数nodejs程序员都会使用 async 和 await 关键字,但是极少有人能真正弄明白 async 和 await 的原理.这篇文章将从零“构建”出 async 和 await 关 ...

  2. Core + Vue 后台管理基础框架2——认证

    1.前言 这块儿当时在IdentityServer4和JWT之间犹豫了一下,后来考虑到现状,出于3个原因,暂时放弃了IdentityServer4选择了JWT: (1)目前这个前端框架更适配JWT: ...

  3. Flutter 日期时间DatePicker控件及国际化

    注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 DatePicker Flutter并没有DatePick ...

  4. vs2017打包exe安装包

    1,安装扩展程序Install Projects 2,在打开的界面搜索Install,找到Install Projects 3,在要打包的项目解决方案下创建一个生成exe的项目 4,在打包项目的文件系 ...

  5. iview的input框校验添加v-modal.number会影响校验,还是依照API使用number来转换number类型

    公司项目使用了iview2.0版本的,有一个需求是需要把里面的值换成number类型并且校验,代码大致如下,使用了v-modal.number来实现转换, <FormItem label=&qu ...

  6. 正则匹配电话号码demo

    public static String doFilterTelnum(String sParam) { String result = sParam; if (sParam.length() < ...

  7. JAVA-迭代器\增强型for循环。(新手)

    //导入的包.import java.lang.reflect.Array;import java.util.*;//创建的一个类.public class zylx1 { //公共静态的主方法. p ...

  8. python https请求报错:SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED]

    python爬虫,使用requests库发送https请求报错:SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] 解决方法: imp ...

  9. [Docker03] Deploy LNMP on Docker

    Deploy MYSQL docker pull mysql 挂载卷保存数据文件 mkdir -p /mysql/data chmod -p 777 /mysql/data MySQL使用过程中的环境 ...

  10. 基础的Linux命令(二)

    本文介绍两大类命令,都是最基础的部分 系统状态监测命令 工作目录切换命令 一.系统状态监测命令 1. ifconfig 命令 用于获取网卡配置与网络状态等信息 如下图:inet后面是 IP 地址,et ...