【题解】Luogu P1627 [CQOI2009] 中位数 排序

基本算法3-2

 


 

大概是用到了排序...吧...

 

计数排序?简单的$O(n+k)$排序,$k$为$max-min$

思想?另开一个数组记录每个数的出现次数,从小到大扫一遍 ->可视化

 

因为要求的是中位数,只关心和目标数的大小关系,所以把比$b$小的设为$-1$,大的设为$1$

最后的答案即为 在$b$前面的$-1$数量 等于 $b$后面的$1$的数量 (就是这一段的和为$0$时)

${\sum_{i=0}^{n*2-1}} l[sum[i]]*r[sum[i]]$ 

因为有负下标所以$+n$后数组要开大一倍

code

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 namespace gengyf{
 4 #define ll long long
 5 const int maxn=2e5+10;
 6 inline int read(){
 7     int f=1,x=0;char s=getchar();
 8     while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
 9     while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
10     return f*x;
11 }
12 int n,b,a[maxn],pos,x[maxn],ans;
13 int sum[maxn],l[maxn],r[maxn];
14 int main(){
15     n=read();b=read();x[b]=0;
16     for(int i=1;i<=n;i++){
17         a[i]=read();if(a[i]==b)pos=i;
18         if(a[i]>b)x[i]=1;
19         if(a[i]<b)x[i]=-1;
20     }
21     l[n]=1;r[n]=1;
22     for(int i=pos-1;i>=1;i--){
23         sum[i]=sum[i+1]+x[i];l[sum[i]+n]++;
24     }
25     for(int i=pos+1;i<=n;i++){
26         sum[i]=sum[i-1]+x[i];r[sum[i]+n]++;
27     }
28     for(int i=0;i<2*n;i++){
29         ans+=l[i]*r[n-i+n];
30     }
31     printf("%d",ans);
32     return 0;
33 }
34 }
35 signed main(){
36   gengyf::main();
37   return 0;
38 }
View Code

 

posted @ 2019-10-18 10:18  喵の耳  阅读(157)  评论(0编辑  收藏  举报