AcWing 499. java
原题链接
简单
作者:
季之秋
,
2021-02-26 20:49:58
,
所有人可见
,
阅读 382
/*
核心思路:(1)找到W和S的关系,二分找到两个临近值取差距最小的
(2)对于每个W求S:对于每个大于W的点求前缀和,小于W的前缀和就等于前一个前缀和值(前缀和大于W的就加上,小于不加)
然后区间前缀和求解,前缀和区间l-r中小于W的我们没加上,小于W的我们加上了,重量前缀和乘数量前缀和
用一个long类型的对m个区间求和,就是每个W的Y值
*/
import java.util.*;
public class Main{
static int N=200010,n,m;
static long sum[]=new long[N];
static long cnt[]=new long[N];
static int v[]=new int[N];
static int w[]=new int[N];
static int L[]=new int[N];
static int R[]=new int[N];
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
m=sc.nextInt();
long S=sc.nextLong();
for(int i=1;i<=n;i++){
w[i]=sc.nextInt();
v[i]=sc.nextInt();
}
for(int i=1;i<=m;i++){
L[i]=sc.nextInt();
R[i]=sc.nextInt();
}
int l=0,r=(int)(1e6+1);
while(l<r){
int mid=l+r+1>>1;
if(get_y(mid)>=S) l=mid;
else r=mid-1;
}
System.out.println(Math.min( get_y(r)-S,S-get_y(r+1)) );
}
static long get_y(int W){
for(int i=1;i<=n;i++){
if(w[i]>=W){
sum[i]=sum[i-1]+v[i];
cnt[i]=cnt[i-1]+1;
}else {
sum[i]=sum[i-1];
cnt[i]=cnt[i-1];
}
}
long res=0;
for(int i=1;i<=m;i++){
res+=(sum[R[i]]-sum[L[i]-1])*(cnt[R[i]]-cnt[L[i]-1]);
}
return res;
}
}