bzoj 1303: [CQOI2009]中位数图

来源:互联网 发布:js pageyoffset 编辑:程序博客网 时间:2024/06/06 19:30

1303: [CQOI2009]中位数图

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 2747  Solved: 1704
[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


这题非常单纯,长度必须为奇数,而且必须是1-n的排列,那么问题就很简单了

统计前缀和,sum[i]==k表示前i个数里大于d的数与小于d的数差为k

还没遍历到d之前,更新flag[k],flag[k]==m表示总共有m个前缀和sum[]==k,

(因为k的范围是[-n, n],数组下标不能为负,所以可以整体+n)

遍历到d之后,对于当前sum[i],所有以第i个元素为结尾中位数为d的连续子序列个数就为flag[sum[i]]!

最后答案就是∑flag[sum[i]]  (d所在位置<=i<=n)


#include<stdio.h>#include<string.h>int a[100005], sum[100005], flag[200010];int main(void){int n, d, i, ans, ok;while(scanf("%d%d", &n, &d)!=EOF){ans = ok = 0;memset(flag, 0, sizeof(flag));flag[n] = 1;for(i=1;i<=n;i++){scanf("%d", &a[i]);if(a[i]>d)  sum[i] = sum[i-1]+1;if(a[i]==d)  sum[i] = sum[i-1], ok = 1;if(a[i]<d)  sum[i] = sum[i-1]-1;if(ok==1)  ans += flag[sum[i]+n];if(ok==0)  flag[sum[i]+n]++;}printf("%d\n", ans);}return 0;}


原创粉丝点击