您的位置:首页 > 其它

[BZOJ1303][CQOI2009]中位数图

2014-04-24 10:32 381 查看
[题目]

给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b。中位数是指把所有元素从小到大排列后,位于中间的数。

[算法]

类似前缀和乱搞

[分析]

预处理sum[i]为1-i中比b大的数比 比b小的数多多少。然后将b出现位置后面的sum的值统计到cnt[i]中。cnt[i]表示sum值为i的个数。很明显刚开始cnt[0]就是以1开头的满足条件序列个数。然后从2到b出现的位置枚举,举例:如果1比b大,那么把cnt[1]加入ans。

[代码]

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <iostream>
using namespace std;

#define MAXN 200100
#define HEHE 100050
int sum[MAXN] = {0};
int num[MAXN] = {0};
int cnt[MAXN] = {0};
int n, k, loc = MAXN;

int main()
{
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++)
{
scanf("%d", &num[i]);
if (num[i] > k)
sum[i] = sum[i-1] + 1;
if (num[i] < k)
sum[i] = sum[i-1] - 1;
if (num[i] == k)
{
loc = i;
sum[i] = sum[i-1];
}
if (i >= loc)
cnt[HEHE + sum[i]]++;
}
int ans = cnt[HEHE + 0];
int now = 0;
for (int i = 2; i <= loc; i++)
{
if (num[i - 1] > k)
now++;
else
now--;
ans += cnt[HEHE + now];
}
printf("%d\n", ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  BZOJ CQOI