51nod-1682 中位数计数

来源:互联网 发布:gnome和x windows 编辑:程序博客网 时间:2024/05/29 18:02

记录一个菜逼的成长。。

题目链接

考虑如何计算一个数的答案:
定义一个b数组,把所有大于自己的值定义为1,小于自己的值定义为-1,等于自己的定义为0。
如果包含这个数的区间这个数是中位数,则定义后的总和为0。
考虑前缀和,那么问题就变成了在这个数两边有多少对相等的数。
可以先把左边的数统计一下,右边的数就可以O(1)查询,时间复杂度O(n)
总时间复杂度O(N2)

这里注意一下sum[i1]==sum[j] 表示的区间才是i-j.
然后这题卡了map,只能用数组计数,又因为有负数所以把所有的前缀和加上8000再统计

#include <bits/stdc++.h>using namespace std;#define pb push_back#define cl(a,b) memset(a,b,sizeof(a))const int maxn = 8000 + 10;int a[maxn],sum[maxn],b[maxn];int cnt[maxn*2];vector<int>ve;int main(){    int n;    while(~scanf("%d",&n)){        for( int i = 1; i <= n; i++ ){            scanf("%d",a+i);        }        int ans;        for( int i = 1; i <= n; i++ ){            sum[0] = 0;            ans = 0;            cl(cnt,0);            cnt[8000]++;            for( int j = 1; j <= n; j++ ){                if(a[j] < a[i])b[j] = -1;                if(a[j] == a[i])b[j] = 0;                if(a[j] > a[i])b[j] = 1;                sum[j] = sum[j-1] + b[j];                if(j < i)cnt[sum[j]+8000] ++;                if(j >= i)ans += cnt[sum[j]+8000];            }            ve.pb(ans);        }        for( int i = 0; i < ve.size(); i++ ){            printf("%d ",ve[i]);        }    }    return 0;}
0 0
原创粉丝点击