基恒最近一直在购买手办送女朋友。因为他想要用最少的价钱买手办送女朋友,所以他每天都记录了手办当天的价格。
他的价格表包括连续N天手办的价格,a_ia
i
表示第i天的价格。基恒认为他已经注意到了连续几天的平均价格和下一天的价格之间的联系。
他想要检验他的想法并且被一个很有趣的问题困扰着:“对于一个给定的P,请问在这N天中,有多少个不同的连续子序列的平均价格大于等于P?”
如果两个连续子序列的起始位置或结束位置不同,那么我们就认为它们是不同的连续子序列。
输入格式
第一行:一个整数N,表示序列的长度。(1 ≤ N ≤ 1,000,0001≤N≤1,000,000)
第二行:N个整数,a_ia
i
表示第i天手办的价格。(0 ≤ a_i ≤ 1,000,000,0000≤a
i
≤1,000,000,000)
第三行:一个整数P。(0 ≤ P ≤ 1,000,000,0000≤P≤1,000,000,000)
输出格式
输出在这N天中,平均价格大于等于P的不同连续子序列的数量。以下是本题的答案,请找出下列代码的问题#include<bits/stdc++.h>
using namespace std;
long long n,a[1100000],sum[1100000],b[1100000];
long long ans[1100000],ni;
long long p;
void guibing(int l,int r){
if(l==r){
return ;
}
long long mid=(l+r)/2;
long long cnt=0;
guibing(l,mid);
guibing(mid+1,r);
int i=l,j=mid+1;
while(i<=mid&&j<=r){
if(b[i]>b[j]){
//cout<<i<<" "<<j<<":"<<b[i]<<" "<<b[j]<<"\n";
ans[++cnt]=b[j++];
ni+=(mid-i+1);
}
else{
ans[++cnt]=b[i++];
}
}
while(i<=mid){
ans[++cnt]=b[i++];
}
while(j<=r){
ans[++cnt]=b[j++];
}
for(int i=1,j=l;i<=cnt,j<=r;i++,j++){
b[j]=ans[i];
}
}
int main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
scanf("%lld",&p);
for(int i=1;i<=n;i++){
sum[i]=sum[i-1]+a[i];
}
for(int i=1;i<=n;i++){
if(a[i]>=p){
ni--;
}
}
for(int i=1;i<=n;i++){
b[i]=sum[i-1]-p*i;
}
// cout<<"\n";
guibing(1,n);
for(int i=1;i<=n;i++){
//cout<<b[i]<<" ";
}
cout<<"\n";
long long tot=n*(n-1)/2;
// cout<<ni<<" ";
printf("%lld",tot-ni);
return 0;
}
最新发布