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