GameFreak @ 2022-07-16 14:34:14
我思路就是二分W+前缀和作判定,但死活不对,WA了4,7,9,11,12,18,求看
评测记录
#include<bits/stdc++.h>
using namespace std;
long long Min(long long x,long long y){
return x<y?x:y;
}
long long Max(long long x,long long y){
return x>y?x:y;
}
long long Abs(long long x){
return x>0?x:-x;
}
long long w[200001],v[200001];
long long l[200001],r[200001];
long long W[200001],V[200001];
long long s;
long long n,m;
long long calc(long long x){
for(int i=1;i<=n;i++)
if(w[i]>=x) W[i]=W[i-1]+1,V[i]=V[i-1]+v[i];
else W[i]=W[i-1],V[i]=V[i-1];
long long ret=0;
for(int i=1;i<=m;i++) ret+=(W[r[i]]-W[l[i]-1])*(V[r[i]]-V[l[i]-1]);
return ret;
}
int main(){
int L=0,R=-0x3f3f3f3f;
scanf("%d%d%lld",&n,&m,&s);
for(long long i=1;i<=n;i++){
scanf("%lld%lld",&w[i],&v[i]);
R=Max(R,w[i]);
}
for(long long i=1;i<=m;i++) scanf("%lld%lld",&l[i],&r[i]);
long long ans=0x3f3f3f3f;
R++;
while(L<R){
long long mid=(L+R)>>1;
long long now=calc(mid);
if(now>=s) L=mid+1,ans=now;
else R=mid;
}
if(ans==s) printf("0");
else printf("%lld",Min(ans,Abs(s-calc(L-1))));
return 0;
}
by Locix_Elaina_Celome @ 2022-07-16 16:37:44
@LQ2024 你在二分过程中取个最小答案
by Locix_Elaina_Celome @ 2022-07-16 16:38:50
int ans=0;
while(L<R){
long long mid=(L+R)>>1;
long long now=calc(mid);
if(now>=s) L=mid+1,ans=now;
else R=mid;
ans=min(ans,abs(now-s));
}
by Locix_Elaina_Celome @ 2022-07-16 16:39:11
最后输出ans
by GameFreak @ 2022-07-16 22:17:06
@fcy_nimas 解决了,谢谢!