[bzoj1303][CQOI2009]中位数图
来自FallDream的博客,未经允许,请勿转载,谢谢。
给定一个n个数排列,求有多少段长度为奇数的区间,中位数是b. n<=100000 时间限制0.1s
我一开始没看到排列,想着怎么还能O(n)做的啊??然后突然发现......
那就很简单啦,把大于b的数看作1,小于的看作-1,从b往两边前缀和,答案就是两边前缀和L[x],R[y]互为相反数的(x,y)的对数。
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #define MN 200000 using namespace std; inline int read() { int x = 0 , f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar();} while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();} return x * f; } int n,b,p,x=0,ans=0; int a[MN+5],L[MN+5]; int main() { x=n=read();b=read(); for(register int i=1;i<=n;++i) { a[i]=read(); if(a[i]>b)a[i]=1; else if(a[i]<b)a[i]=-1; else {a[i]=0;p=i;} } for(register int i=p-1;i;--i) { x+=a[i]; ++L[x]; } x=n;ans=++L[n]; for(register int i=p+1;i<=n;++i) x-=a[i],ans+=L[x]; printf("%d\n",ans); return 0; }
FallDream代表秋之国向您问好!
欢迎您来我的博客www.cnblogs.com/FallDream