博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ1303: [CQOI2009]中位数图
阅读量:4581 次
发布时间:2019-06-09

本文共 1168 字,大约阅读时间需要 3 分钟。

【传送门:】


简要题意:

  给出一条n个数的序列,保证序列里的数为1~n,且互不相等,再给出一个数b,求出以b为中位数的长度为奇数的子序列个数


题解:

  显然要你求以b为中位数的长度为奇数的子序列,其实就是求包含b的,以b为中位数的子序列,因为序列中的数互不相等,而且求的是奇数长度

  那我们把序列中大于b的,改值为-1,小于b的,改值为1,等于b,就是b的位置,直接记录b的位置

  那显然就是一个求前缀和问题,首先定义L,R数组,分别表示以b所在的位置向前后延伸所得到的和的个数

  简单地用样例来说明:

   7   4

   5   7   2   4   3   1   6

  -1  -1   1   0   1   1  -1

  b的位置是4,向前后延伸,先向前,向前一位后,L[1]++,向前两位后,L[1+(-1)=0]++,向前三位后,L[0-1=-1]++,就是这样,R数组的求法也是这样

  那么答案就是ΣL[i]*R[-i](0<=i<=n)

  那么因为C++中的数组是访问不到负数的,所以就把得到的和加上n再记录到L数组,这样求解的时候就是ΣL[i+n]*R[n-i](0<=i<=n)


参考代码:

#include
#include
#include
#include
#include
using namespace std;int a[110000],s[110000];int mid[110000];int L[210000];int R[210000];int main(){ int n,b; scanf("%d%d",&n,&b); int x=0; memset(s,0,sizeof(s)); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); if(a[i]>b) s[i]=-1; if(a[i]
=1;i--) { sum+=s[i]; L[sum+n]++; } int ans=0; sum=0; for(int i=x+1;i<=n;i++) { sum+=s[i]; R[sum+n]++; } for(int i=-n;i<=n;i++) { ans+=L[i+n]*R[n-i]; } printf("%d\n",ans); return 0;}

 

 

 

转载于:https://www.cnblogs.com/Never-mind/p/7601410.html

你可能感兴趣的文章
子节点填充父元素除去一固定高度后的剩余高度
查看>>
[原]IOS 后台发送邮件
查看>>
(转)JAVA Calendar详解
查看>>
转: 编码,charset,乱码,unicode,utf-8与net简单释义
查看>>
C#--正则匹配
查看>>
5.30 考试修改+总结
查看>>
BA-设计施工调试流程
查看>>
C#-CLR各版本特点
查看>>
css3背景透明文字不透明
查看>>
《java JDK7 学习笔记》之接口与多态
查看>>
android的用户定位(一)
查看>>
设计模式-结构型模式,外观模式(6)
查看>>
[Java] 遍历HashMap和HashMap转换成List的两种方式
查看>>
mongodb
查看>>
LeetCode 46. Permutations
查看>>
jmeter- 性能测试3:聚合报告(Aggregate Report )
查看>>
JavaScript高级程序设计---学习笔记(二)
查看>>
vim 插件的学习
查看>>
Uncaught SyntaxError: Unexpected token ILLEGAL
查看>>
一个预处理定义的问题
查看>>