二分答案的边界问题还是要注意
double挨着,int+1-1,
此题用到long long,所以初始化ans要足够大,前缀和优化
依然根据check答案大小左右mid,虽然有s,但是有了+1-1加持所以能够自动推出
#include<bits/stdc++.h> #define int long long #define rep(i,x,y) for(register int i=x;i<=y;i++) using namespace std; const int N=2e6+50; int n,m,s,mi,mx,ans,w[N],v[N],l[N],r[N]; inline int read(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f;} inline int aabs(int x){return x>0?x:-x;} int sum[N],cnt[N]; bool check(int mid){int y=0; memset(sum,0,sizeof sum); memset(cnt,0,sizeof cnt); rep(i,1,n){ sum[i]=sum[i-1],cnt[i]=cnt[i-1]; if(w[i]>=mid) sum[i]+=v[i],cnt[i]++; }rep(i,1,m) y+=(cnt[r[i]]-cnt[l[i]-1])*(sum[r[i]]-sum[l[i]-1]); ans=min(ans,aabs(y-s)); if(y>s) return 1; else return 0; } signed main(){ n=read(),m=read(),s=read();ans=mi=999999999999999999; rep(i,1,n) w[i]=read(),v[i]=read(),mi=min(mi,w[i]),mx=max(mx,w[i]); rep(i,1,m) l[i]=read(),r[i]=read(); int l=mi,r=mx; while(l<=r) { int mid=(l+r)>>1; bool FG=check(mid); if(FG) l=mid+1; else r=mid-1; } printf("%lld\n",ans);return 0; }
怀挺
原文地址:https://www.cnblogs.com/asdic/p/9737564.html
时间: 2024-10-15 05:04:33