一道很水的二分答案的题。很明显已知参数W,就可以很容易的算出检测值。并且 Y−S 是一个单调递减的函数
然而我在二分的时候写成了high>low,正确的是low<=high。
少了30分 %>_<%
数据下载
#include <iostream>
#include <cstdio>
#define MAXN 200005
#define LL long long int
#define abs(a) ((a)>0?(a):(-(a)))
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
int n ,m ,l[MAXN] ,r[MAXN] ,high ,low ,mid ;
int w[MAXN] ,v[MAXN] ;
LL s ,sum[MAXN] ,cnt[MAXN] ;
LL cal(int mid)
{
for(int i=1;i<=n;++i)
{
sum[i]=sum[i-1] ,cnt[i]=cnt[i-1] ;
if(w[i]>=mid)
sum[i]+=v[i] ,++cnt[i];
}
LL ans=0;
for(int i=1;i<=m;++i)
ans+=(cnt[r[i]]-cnt[l[i]])*(sum[r[i]]-sum[l[i]]);
return ans;
}
int main()
{
scanf("%d%d%lld",&n,&m,&s);
for(int i=1;i<=n;++i)
{
scanf("%d%d",&w[i],&v[i]);
if(high<w[i])high=w[i];
}
for(int i=1;i<=m;++i)
{
scanf("%d%d",&l[i],&r[i]);
--l[i];
}
low=1;
int mid ;
LL ans=1000000005000ll ,temp ;
while(low<=high)//注意!!
{
mid=(low+high)/2 ;
temp=cal(mid);
if(temp==s)
{
puts("0");
break;
}
ans=min(ans,abs(temp-s));
if(temp>s)
low=mid+1;
else high=mid-1;
}
printf("%lld\n",ans);
return 0;
}