51nod 1682 中位数计数

1682 中位数计数
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题

中位数定义为所有值从小到大排序后排在正中间的那个数,如果值有偶数个,通常取最中间的两个数值的平均数作为中位数。

现在有n个数,每个数都是独一无二的,求出每个数在多少个包含其的区间中是中位数。

Input
第一行一个数n(n<=8000)
第二行n个数,0<=每个数<=10^9
Output
N个数,依次表示第i个数在多少包含其的区间中是中位数。
Input示例
5
1 2 3 4 5
Output示例
1 2 3 2 1
/*
51nod 1682 中位数计数

problem:
给你n个数,求出每个数在多少个包含其的区间中是中位数

solve:
如果a[i]在区间[l,r]是中位数,那么区间中大于a[i]和小于a[i]的数一样多. up[r]-up[l] == down[r]-down[l]
--> up[r]-down[r] == up[l]-down[l]. 就变成了当前i前面有多少个数up-down与其相等.
所以可以从中间往两边记录并统计.

hhh-2016/09/03-21:08:16
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <math.h>
#include <queue>
#include <set>
#include <map>
#define lson  i<<1
#define rson  i<<1|1
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define scanfi(a) scanf("%d",&a)
#define scanfs(a) scanf("%s",a)
#define scanfl(a) scanf("%I64d",&a)
#define scanfd(a) scanf("%lf",&a)
#define key_val ch[ch[root][1]][0]
#define eps 1e-7
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
const ll mod = 1000000007;
const int maxn = 8080;
const double PI = acos(-1.0);
int n;
ll num[maxn*2];
int a[maxn];

ll cal(int id)
{
    int upcnt =0 ;
    int docnt = 0;
    memset(num,0,sizeof(num));
    num[8000] = 1;
    for(int i = id-1; i >= 1; i--)
    {
        if(a[i] > a[id]) upcnt++;
        if(a[i] < a[id]) docnt++;
        num[upcnt-docnt+8000] ++;
    }
    ll ans = 0;
    upcnt = docnt = 0;
    for(int i = id; i <= n; i++)
    {
        if(a[i] > a[id]) upcnt++;
        if(a[i] < a[id]) docnt++;
        ans += num[docnt-upcnt+8000];
    }
    return ans;
}

int main()
{
    while(scanfi(n) != EOF)
    {
        for(int i = 1; i<= n; i++)
            scanfi(a[i]);

        for(int i = 1; i<= n; i++)
        {
            printf("%I64d%c",cal(i),i == n ? '\n':' ' );
        }
    }
    return 0;
}

  

posted @ 2016-09-03 21:14  Przz  阅读(398)  评论(0编辑  收藏  举报