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; }