传送门:https://www.luogu.org/problem/P1314
本SB犯得错误:
- 不开longlong见祖宗......
- 既没有在check中更新答案,又没有最后输出判断ans(l);和ans(l+1)哪个是更优的
二分参数W,然后前缀和一下,逐个计算检验值Y。
不开longlong见祖宗
不开longlong见祖宗
不开longlong见祖宗
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define R register typedef long long ll; using namespace std; ll n,m,s,ql[200100],qr[200100],w[200100],v[200100],l=1e18,r=-1e18; ll cnt[200100]; ll sum[200100]; inline ll ans(ll fl){ ll tot=0; memset(sum,0,sizeof(sum));memset(cnt,0,sizeof(cnt)); for(R int i=1;i<=n;i++){ if(w[i]>=fl) sum[i]+=v[i],cnt[i]++; sum[i]+=sum[i-1];cnt[i]+=cnt[i-1]; } for(R int i=1;i<=m;i++){ tot+=1ll*(sum[qr[i]]-sum[ql[i]-1])*(cnt[qr[i]]-cnt[ql[i]-1]); } return tot; } int main (){ scanf("%lld%lld%lld",&n,&m,&s); for(R int i=1;i<=n;i++) scanf("%lld%lld",&w[i],&v[i]),l=min(l,w[i]),r=max(r,w[i]); for(R int i=1;i<=m;i++) scanf("%lld%lld",&ql[i],&qr[i]); while(l<r){ int mid=(l+r+1)>>1; if(ans(mid)>=s) l=mid; else r=mid-1; } printf("%lld ",min(abs(ans(l)-s),abs(ans(l+1)-s))); return 0; }