首先我们来看看观察每个区间的值
图片说明
就以题目中的示例为例子解释一下
图片说明

对应区间段1-5
由于可加的物品的重量必须大于等于W(4)
故在1-5中只有4,5两个可加贡献为 25+25=20;2是因为有两个数符号条件
在2-4中,只有4一个可加贡献为1*5=5;
3-3中,没有可以加的贡献0
故这样当w取4时候,贡献一共为25

这样我们可以看出这道题主要是求出某个区域的的值,这样我们便采用前缀和
我们可以采用一个sum数组来记录从前缀和,sum[i]表示从1到i之间所有有效数字的和
如果我们要求l,r之间的有效值,则可以用sum[r]-sum[i-1];
同理采用cnt数组来记录某个区间段有效物品的个数,cnt[i]表示从1到i之间有效物品的个数,
l,r之间的有效值个数即为cnt[r]-cnt[l-1];
故对应一个区间段的V值即为(cnt[r]-cnt[l-1])*(sum[r]-sum[l-1]);

#include<bits/stdc++.h>
using namespace std;
long long n,m,s;
long long sum[1000005];//用于前缀和存储
long long weight[1000005];//存储重量
long long value[1000005];//存储价值
int lefti[1000005];//存储区段的左结点
int righti[1000005];//存储区段右结点
int cnt[1000005];//存储有效数组的前缀
long long getsum(int w)//求出W=w时候,全部区域的V值和
{
    long long ans=0;
    for(int i=1;i<=n;i++)//先求出
    {
        if(weight[i]>=w)//如果满足条件
        {
            sum[i]=sum[i-1]+value[i];//加上这个物品的价值
            cnt[i]=cnt[i-1]+1;//有效值加1
        }
        else
        {
            sum[i]=sum[i-1];
            cnt[i]=cnt[i-1];
        }
    }
    for(int i=1;i<=m;i++)
    {
        ans+=(cnt[righti[i]]-cnt[lefti[i]-1])*(sum[righti[i]]-sum[lefti[i]-1]);
    }
    return ans;
}
int main()
{
    cnt[0]=0;
    sum[0]=0;
    int maxsize=-1;//用于记录最大值,便于后面确定二分法的起点
    scanf("%lld%lld%lld",&n,&m,&s);
    for(int i=1;i<=n;i++)
    {
       scanf("%lld %lld",&weight[i],&value[i]);
       if(weight[i]>maxsize) maxsize=weight[i];
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d",&lefti[i],&righti[i]);
    }
    int l=0,r=maxsize+1;
    int mid=(l+r+1)>>1;
    int vis=0;//判断是否有差为0情况
    while(l<r)
    {
        if(getsum(mid)>s)因为大于标准,则说明w取小了让很多物体都符合条件,故要增加w
        {
            l=mid;
        }
        else if(getsum(mid)<s)
        {
            r=mid-1;
        }
        else
        {
            printf("0");
            vis=1;
            break;
        }
        mid=(l+r+1)>>1;
    }
    if(!vis)  printf("%lld",min(abs(s-getsum(r+1)),abs(getsum(r)-s)));  
}

最后祝大家天天AC,坚持下去!