【题解】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 }