连div3的题都不会写了。。。。
题意简单来说就是给你一串数字,求有多少个区间,使得区间内的数字排序后中位数恰好是m。
题解的做法是先找出所有满足中位数大于等于m的区间,然后减去满足中位数大于等于m+1的区间,就可以得到中位数为m的区间数了。
如何统计中位数大于等于m的区间?必须满足区间内不小于m的数值的数量>小于m的数值的数量。于是我们可以使用预处理出noless-less的前缀和k,那么对于一个右端点j,满足的左端点i仅需满足pre[i]
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2*1e5+15;
const int maxm=1005;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
int n,m;
int a[maxn];
ll calc(int val){
vector<int> vec(2*n+1);
vec[n]=1;
ll sum=n;
ll add=0;
ll ans=0;
for(int i=0;i<n;i++){
if(a[i]<val){
sum--;
add-=vec[sum];
}
else{
add+=vec[sum];
sum++;
}
ans+=add;
vec[sum]++;
}
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
ll ans=calc(m)-calc(m+1);
printf("%lld\n",ans);
return 0;
}