51NOD 1682 中位數計數

2021-07-26 20:14:17 字數 1787 閱讀 6411

1682 中位數計數

基準時間限制:1 秒 空間限制:131072 kb 分值: 40 難度:4級演算法題 收藏 關注

中位數定義為所有值從小到大排序後排在正中間的那個數,如果值有偶數個,通常取最中間的兩個數值的平均數作為中位數。

現在有n個數,每個數都是獨一無二的,求出每個數在多少個包含其的區間中是中位數。

input

第一行乙個數n(n<=8000)

第二行n個數,0

<=每個數<=10^9

output

n個數,依次表示第i個數在多少包含其的區間中是中位數。

input示例51

2345

output示例12

321joe (題目提供者)

以a[i]作為基準

新建陣列c

c[j] = a[j]>a[i]? 1 : a[j]==a[i] ? 0 : -1

csum[j]=c[j]+c[j+1]+....+c[i]; //j<=i

csum[j]=c[i]+c[i+1]+...c[j]; //j>=i

如果a[s….e] 排序後 a[i]是中位數 那以a[i]為基準 必定有:csum[s]+csum[e]=0

所以 :

以a[i]為基準計算csum

ans =

∑ (csum[s]+csum[e]==0) s<=i,i<=e

o(n^3) 不給力

如果用乙個num陣列 記錄下num[k]=

∑ csum[s]==k (s<=i)

ans =

∑ num[-csum[e]] (e>=i)

複雜度為o(n^2)

num下標可能為負數 加個offset=n即可

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

//#include

using

namespace

std;

#define ll long long

#define ull unsigned long long

#define pii pair

#define inf 1000000007

#define pll pair

#define pid pair

const

int n = 8000;

int a[n+5];

int s[n+5];

int num[2*n+10];

int cmp(int a,int b)

if(a>b)

return0;}

void slove(int n)

int ans=num[n];

for(int j=i+1;j<=n;++j)

printf("%d ",ans);

}}int main()

slove(n);

return

0;}

51Nod 1682 中位數計數

acm模版 這裡,我們可以分析得到,符合規則的區間有四種形式,分別是 i 1 j i 2 i j 3 j i j 4 而這裡,第一種不用過多處理,就是1 第2種和第3種類似,所以,我們需要求出來i之前的num的匹配情況,和i之後的num的匹配情況 而第四種要求的是,在第2種和第3種的基礎上,進行匹配...

51Nod 1682 中位數計數

中位數定義為所有值從小到大排序後排在正中間的那個數,如果值有偶數個,通常取最中間的兩個數值的平均數作為中位數。現在有n個數,每個數都是獨一無二的,求出每個數在多少個包含其的區間中是中位數。input 第一行乙個數n n 8000 第二行n個數,0 每個數 10 9 output n個數,依次表示第i...

51nod 1682 中位數計數

1682 中位數計數 基準時間限制 1 秒 空間限制 131072 kb 分值 40 難度 4級演算法題 中位數定義為所有值從小到大排序後排在正中間的那個數,如果值有偶數個,通常取最中間的兩個數值的平均數作為中位數。現在有n個數,每個數都是獨一無二的,求出每個數在多少個包含其的區間中是中位數。inp...