只搞到了 30pts 求助
我的思路:先统计所有sum>=L的子串数量ansL和sum<=R的子串数量ansR,然后结果为ansL+ansR-n*(n+1)/2。
思路大概没问题,可是代码萎了,求大佬帮忙查错
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,L,R;
long long ansL,ansR,a[100005],b[100005],cpy[100005];
void merge(int l,int r)//归并排序
{
int mid=(l+r)/2;
int tot=l,i=mid+1,j=l;
for(;i<=r;i++)
{
while(j<=mid&&a[i]>=a[j-1]) b[tot++]=a[j++];
b[tot++]=a[i];
}
while(j<=mid) b[tot++]=a[j++];
for(int k=l;k<=r;k++) a[k]=b[k];
return ;
}
void CDQ1(int l,int r)//求ansL
{
if(l==r) return ;
int mid=(l+r)/2;
CDQ1(l,mid),CDQ1(mid+1,r);
int i=mid+1,j=l;
for(;i<=r;i++)
{
while(j<=mid&&a[i]-a[j-1]>=L) j++;
ansL+=j-l;
}
merge(l,r);
return ;
}
void CDQ2(int l,int r)//求ansR
{
if(l==r) return ;
int mid=(l+r)/2;
CDQ2(l,mid),CDQ2(mid+1,r);
int i=mid+1,j=l;
for(;i<=r;i++)
{
while(j<=mid&&a[i]-a[j-1]>R) j++;
ansR+=mid-j+1;
}
merge(l,r);
return ;
}
int main()
{
scanf("%d%d%d",&n,&L,&R);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
if(a[i]>=L) ansL++;
if(a[i]<=R) ansR++;
a[i]+=a[i-1];
}
memcpy(cpy,a,sizeof cpy);
CDQ1(1,n);
memcpy(a,cpy,sizeof a);
CDQ2(1,n);
printf("%lld\n",ansL+ansR-1ll*n*(n+1)/2);
return 0;
}
求大佬帮忙查错或hack数据
感激不尽>_<