【题意】
给出一串数字,问中位数大于等于X的连续子串有几个。(这里如果有偶数个数,定义为偏大的那一个而非中间取平均)
【思路】
下面的数据规模也小于原题,所以要改成__int64才行。没找到测试数据,自己编的几组。简单来说读入每个数,大于等于中位数设为1,小于设为-1,前i个数的和建立一个树状数组,求逆序对。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int MAXN=10000; 7 struct Rec 8 { 9 int num,orinum; 10 bool operator < (const Rec &x) const 11 { 12 return num<x.num; 13 } 14 }; 15 int n,x; 16 Rec b[MAXN]; 17 int a[MAXN],e[MAXN]; 18 int ans=0; 19 20 int lowbit(int x) 21 { 22 return (x & (-x)); 23 } 24 25 void add(int p,int x) 26 { 27 int i=p; 28 while (i<=(2*n+1)) 29 { 30 e[i]+=x; 31 i=i+lowbit(i); 32 } 33 } 34 35 int sum(int p) 36 { 37 int s=0; 38 int i=p; 39 while (i>0) 40 { 41 s+=e[i]; 42 i=i-lowbit(i); 43 } 44 return s; 45 } 46 47 int main() 48 { 49 /*input*/ 50 scanf("%d%d",&n,&x); 51 int num[MAXN]; 52 53 a[0]=0; 54 for (int i=1;i<=n;i++) 55 { 56 a[i]=a[i-1]; 57 scanf("%d",&num[i]); 58 if (num[i]>=x) a[i]++; 59 if (num[i]<x) a[i]--; 60 } 61 62 63 add(n+1,1); 64 for (int i=1;i<=n;i++) 65 { 66 ans+=sum(a[i]+n+1); 67 add(a[i]+n+1,1); 68 } 69 70 cout<<ans<<endl; 71 72 return 0; 73 }