题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5701
这题n方可过,显然满足条件的区间必是含奇数个数的区间,对于每个数,
先往右扫一遍,求得其右边比其大的和比其小的数的个数的差x,然后再往
左扫一遍,求其左边比起小的数和比起大的数的差,若一个数在这个区间为
中位数,则若其右边比它大的比比它小的多x(有点绕),则其左边相反小的要
比大的多x,这样x才能正好在中间位置,用一个数组记录一下差值为某个数
的个数即可,注意要算上这个数自己。
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int const maxn = 8005;
int const con = 8002;
int num[maxn],vis[maxn*2];
int main() {
int n,cnt,ans;
while(~scanf("%d",&n)) {
for(int i = 1; i <= n; i++) {
scanf("%d",&num[i]);
}
for(int i = 1; i <= n; i++) {
cnt = 0;
ans = 0;
memset(vis,0,sizeof(vis));
vis[con]++; ///统计上自己
//求第i个数右侧比i大-比i小的的差
for(int j = i+1; j <= n; j++) {
if(num[j]>num[i])
cnt++;
else
cnt--;
vis[con+cnt]++; ///由于cnt可能是负数,所以给它加上一个比较大的数
}
ans += vis[con]; ///加上自己本身这个答案
cnt = 0;
for(int j = i-1; j > 0; j--) {
if(num[j]<num[i])
cnt++;
else
cnt--;
ans += vis[con+cnt];
}
if(i != n)
printf("%d ",ans);
else
printf("%d\n",ans);
}
}
return 0;
}