bzoj1303[CQOI2009]中位数图

bzoj1303[CQOI2009]中位数图

题意:

给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b。

题解:

首先将数组中所有小于b的数置为-1,等于的置为0,大于的置为1。然后对b及其右边的数的前缀和(b的位置到该位置所有数的和)出现个数建一个数组r,对b左边的数的每个后缀和(该位置到b的位置所有数的和)的相反数在r中的数相乘就是答案。实际上,这种把数转化成1、-1、0的方法十分常用,但是我不会。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define inc(i,j,k) for(int i=j;i<=k;i++)
 5 #define dec(i,j,k) for(int i=j;i>=k;i--)
 6 using namespace std;
 7 
 8 int l[400000],r[400000],s,n,b,a[200000],p;
 9 int main(){
10     scanf("%d%d",&n,&b); 
11     inc(i,1,n){
12         int a1; scanf("%d",&a1); if(a1==b)a[i]=0,p=i; if(a1<b)a[i]=-1; if(a1>b)a[i]=1;
13     }
14     l[p+1]=0; dec(i,p,1)l[i]=l[i+1]+a[i];
15     memset(r,0,sizeof(r)); s=0; inc(i,p,n)s=s+a[i],r[s+n]++;
16     int ans=0; inc(i,1,p)ans+=r[-l[i]+n];
17     printf("%d",ans);
18 }

 

20160401

posted @ 2016-07-21 20:15  YuanZiming  阅读(234)  评论(0编辑  收藏  举报