1303: [CQOI2009]中位数图
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 1974 Solved: 1268
[Submit][Status][Discuss]
Description
给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b。中位数是指把所有元素从小到大排列后,位于中间的数。
Input
第一行为两个正整数n和b ,第二行为1~n 的排列。
Output
输出一个整数,即中位数为b的连续子序列个数。
Sample Input
7 4
5 7 2 4 3 1 6
Sample Output
4
HINT
第三个样例解释:{4}, {7,2,4}, {5,7,2,4,3}和{5,7,2,4,3,1,6}
N<=100000
Source
题解:
发现了一个方法:
预处理一个权值数组,如果当前位置小于b为-1大于b为1,等于b为0
应用前缀和的思想,去做两个数组lsum,rsum。
不过,会出现负权,都+n即可
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
#define maxn 100010
int n,b;
int a[maxn],qz[maxn],ans=0,loc;
int lsum[2*maxn],rsum[2*maxn],sum;
int main()
{
n=read(),b=read();
for (int i=1; i<=n; i++)
{a[i]=read();if (a[i]==b) loc=i;}
for (int i=1; i<=n; i++)
if (a[i]<b) qz[i]=-1; else qz[i]=1;
lsum[n]=rsum[n]=1;
sum=0;
for (int i=loc-1; i>=1; i--)
sum+=qz[i],lsum[sum+n]++;
sum=0;
for (int i=loc+1; i<=n; i++)
sum+=qz[i],rsum[sum+n]++;
for (int i=0; i<=2*n; i++) ans+=lsum[i]*rsum[2*n-i];
printf("%d\n",ans);
return 0;
}

本文介绍了一道经典算法题目“CQOI2009中位数图”,任务是统计一个排列中长度为奇数的连续子序列中位数为特定值的数量。通过预处理权值数组并运用前缀和思想,巧妙地解决了可能出现的负权问题。
121

被折叠的 条评论
为什么被折叠?



