正题
题目链接:https://www.ybtoj.com.cn/contest/68/problem/1
题目大意
nnn个数字的序列,求有多少个区间[l,r][l,r][l,r]的平均值在[L,R][L,R][L,R]的范围内。
解题思路
如果让每个ai−xa_i-xai−x,那么统计区间和大于等于111的区间数量就可以统计平均值大于xxx的区间数量,那么我们让平均值大于等于LLL的减去平均值大于RRR的。
为了方便不离散化,我们让下标和数值互换一下,注意计算RRR时因为是大于的所以不能和LLL的方法相同。
时间复杂度O(nlogn)O(n\log n)O(nlogn)
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lowbit(x) (x&-x)
#define ll long long
using namespace std;
const ll N=5e5+10;
ll n,L,R,p[N],w[N],t[N],a[N],fl;
bool cmp(ll x,ll y)
{return (w[x]==w[y])?(fl?(x>y):(x<y)):(w[x]<w[y]);}
void Change(ll x,ll val){x++;while(x<=n+1){t[x]+=val;x+=lowbit(x);}return;
}
ll Ask(ll x){ll ans=0;x++;while(x){ans+=t[x];x-=lowbit(x);}return ans;
}
ll solve(ll x,bool flag){fl=flag;memset(t,0,sizeof(t));for(ll i=1;i<=n;i++)w[i]=w[i-1]+a[i]-x,p[i]=i;ll ans=0;p[n+1]=0;sort(p+1,p+2+n,cmp);for(ll i=1;i<=n+1;i++){ans+=Ask(p[i]);Change(p[i],1);}return ans;
}
int main()
{freopen("sequence.in","r",stdin);freopen("sequence.out","w",stdout);scanf("%lld%lld%lld",&n,&L,&R);for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);ll a=solve(L,0)-solve(R,1);ll b=n*(n+1ll)/2ll,d=__gcd(a,b);a/=d;b/=d;if(!a)printf("0\n");else if(a==b)printf("1\n");else printf("%lld/%lld\n",a,b);return 0;
}