源代码: #include<cstdio> int n,L,R,Ans,i[500001],j[500001],Sum[500001]; int GCD(int t1,int t2) { return t2?GCD(t2,t1%t2):t1; } void Merge1(int t1,int t2) //细节的繁琐处理。 { if (t1==t2) return; int X=t1,Y=((t1+t2)>>1)+1,Z=Y-1,Num=t1; Merge1(X,Z); Merge1(Y,t2); while (X<=Z&&Y<=t2) if (Sum[X]<Sum[Y]) j[Num++]=Sum[X++]; else { Ans+=Z-X+1; j[Num++]=Sum[Y++]; } while (X<=Z) j[Num++]=Sum[X++]; while (Y<=t2) j[Num++]=Sum[Y++]; for (int a=t1;a<=t2;a++) Sum[a]=j[a]; } void Merge2(int t1,int t2) { if (t1==t2) return; int X=t1,Y=((t1+t2)>>1)+1,Z=Y-1,Num=t1; Merge2(X,Z); Merge2(Y,t2); while (X<=Z&&Y<=t2) if (Sum[X]<=Sum[Y]) j[Num++]=Sum[X++]; else { Ans+=Z-X+1; j[Num++]=Sum[Y++]; } while (X<=Z) j[Num++]=Sum[X++]; while (Y<=t2) j[Num++]=Sum[Y++]; for (int a=t1;a<=t2;a++) Sum[a]=j[a]; } int Solve1(int S) { Sum[0]=Ans=0; for (int a=1;a<=n;a++) { Sum[a]=Sum[a-1]+i[a]-S; if (Sum[a]<=0) Ans++; } Merge1(1,n); return Ans; } int Solve2(int S) //为什么不能统一,因为平均数不一定是整数啊! { Sum[0]=Ans=0; for (int a=1;a<=n;a++) { Sum[a]=Sum[a-1]+i[a]-S; if (Sum[a]<0) Ans++; } Merge2(1,n); return Ans; } int main() //凡事还得想想逆序对。 { scanf("%d%d%d",&n,&L,&R); for (int a=1;a<=n;a++) scanf("%d",&i[a]); int t1=Solve1(R)-Solve2(L); int t2=n*(n+1)>>1; if (t1%t2) { int t=GCD(t1,t2); printf("%d/%d",t1/t,t2/t); } else printf("%d",t1/t2); return 0; } /* 题目要求求平均数为[L,R]的区间个数,可以转化为,求平均数为[1,R]区间个数-平均数为[1,L)区间个数。 以[1,R]为例, (i[a]+i[a+1]+...+i[a+k-1])/k<=R (i[a]-R)+(i[a+1]-R)+...+(i[a+k-1]-R)<=0 令Sum[]为前缀和数组, Sum[a+k-1]+Sum[a]<=0 即为求Sum[]的逆序对数,以此类推,注意细节。 */