BZOJ-1303 [CQOI2009]中位數圖(字首和+計數)
阿新 • • 發佈:2020-12-07
題目描述
給出 \(1,2,\cdots,n(n\leq 10^5)\) 的一個排列,統計該排列有多少個長度為奇數的連續子序列的中位數是 \(b\)。中位數是指把所有元素從小到大排列後,位於中間的數。
分析
讀入的時候把大於 \(b\) 的數賦值為 \(1\),小於 \(b\) 的數賦值為 \(-1\),\(b\) 的下標設為 \(pos\)。設 \(l[i]\) 為 \(pos\) 左邊的字尾和為 \(i\) 的字尾數目,\(r[i]\) 為 \(pos\) 右邊的字首和為 \(i\) 的字首數目。列舉 \(-10^5\leq x\leq 10^5\),\(l[x]\) 可以與 \(r[-x]\)
程式碼
#include<bits/stdc++.h> using namespace std; const int N=1e5; int a[N+10],l[4*N+10],r[4*N+10]; inline int read() { int x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();} while (isdigit(ch)){x=x*10+ch-48;ch=getchar();} return x*f; } int main() { int n,b,pos; cin>>n>>b; for(int i=1;i<=n;i++) { a[i]=read(); if(a[i]>b) a[i]=1; else if(a[i]==b) pos=i; else a[i]=-1; } l[N+0]=r[N+0]=1; int sum=0; for(int i=pos-1;i>=1;i--) { sum=sum+a[i]; l[N+sum]++; } sum=0; for(int i=pos+1;i<=n;i++) { sum=sum+a[i]; r[N+sum]++; } long long ans=0; for(int i=0;i<=N+100000;i++) ans=ans+l[i]*r[2*N-i]; cout<<ans<<endl; return 0; }