[CQOI2009] 中位数

给出 (1~n) 的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是 (b)。中位数是指把所有元素从小到大排列后,位于中间的数。

Solution

(这个题为什么会被打上数学标签?)

由于给出的是排列,我们找到这个数在哪,然后考虑它左边和右边的数

我们把比它大的数都变成 (1) ,小的都变成 (-1)

向左的后缀和值构成的多重集 (A),向右的 (B)

现在就是要在向左和向右里面各找出一个数相加和为 (0),求方案数

拿桶搞搞就可以了

#include <bits/stdc++.h>
using namespace std;

#define int long long
int n,k,x[100005],s[200005],a[200005],b[200005];

signed main() {
    ios::sync_with_stdio(false);
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>x[i];
    int pos=0;
    for(int i=1;i<=n;i++) if(x[i]==k) pos=i;
    for(int i=1;i<=n;i++) {
        if(x[i]>k) s[i]=1;
        if(x[i]<k) s[i]=-1;
    }
    for(int i=pos-1;i;--i) s[i]+=s[i+1];
    for(int i=pos+1;i<=n;i++) s[i]+=s[i-1];
    for(int i=1;i<=pos;i++) a[s[i]+100000]++;
    for(int i=pos;i<=n;i++) b[s[i]+100000]++;
    int ans=0;
    for(int i=0;i<=200000;i++) ans+=a[i]*b[200000-i];
    cout<<ans;
}
原文地址:https://www.cnblogs.com/mollnn/p/12298831.html