思路:求某个区间的和小于t,首先肯定是要用前缀和的,然后我们可以将不等式转换一下,得到:sum[r]-t<sum[l-1],所以我们只需要求出在r之前有多少个从下标1开始的区间和大于sum[r]-t。
这样我们很容易想到这是一个求逆序对的问题,每次我们只需要插入sum[r]即可,进行查询操作之前,我们需要将每个sum[r]-t和每个sum[r]都进行离散化,然后查询符合要求的个数就可以了。
Code:
#define fi first
#define se second
const int N=2e6+5,mod=998244353;
int a[N],b[N],tr[N];
int cnt,n,m;
map<int,int> mp;
void add(int x)
{
for(;x<=cnt;x+=(x&-x)) tr[x]+=1;
}
int ask(int x)
{
int res=0;
for(;x;x-=(x&-x)) res+=tr[x];
return res;
}
void solve()
{
cin>>n>>m;
vector<int> v(n+1,0);
for(int i=1;i<=n;i++)
{
cin>>v[i];
a[i]=a[i-1]+v[i];
mp[a[i]-m]=mp[a[i]]=1;
}
map<int,int> h;
for(auto it:mp)
h[it.fi]=++cnt;
int sum=0;
for(int i=1;i<=n;i++)
{
if(h[a[i]-m]<cnt)
{
sum+=ask(cnt)-ask(h[a[i]-m]);
// cout<<i<<' '<<sum<<endl;
}
add(h[a[i]]);
if(a[i]<m) sum++;
}
cout<<sum;
}