以前从不发有关二分的博客,之所以发这篇,是因为这个二分太有意思了
题意:一共有k种题目,每场比赛每种题目数量要限制在 [ l i , r r ] [l_i,r_r] [li,rr],每场比赛题目总数要在 [ L , R ] [L,R] [L,R],每种题目,有 a i a_i ai道,求最多可以进行多少次比赛
思路考虑二分:
二分比赛场数
判定方式如下:如果每道题目的数量到满足去最小的时候, a i a_i ai大于其和,即 a i > = m i d ∗ l i a_i>=mid*l_i ai>=mid∗li。
这个时候还要考虑 L > ∑ l i L>{\sum}l_i L>∑li,那么把所有剩余的能加的题目加起来看,能不能满足这个条件,即 s u m > = ( L − ∑ l i ) ∗ m i d sum>=(L-{\sum}l_i)*mid sum>=(L−∑li)∗mid,其中剩余的且能加数量为 ∑ m i n ( m i d ∗ ( r i − l i ) , a i − m i d ∗ l i ) {\sum}min(mid*(r_i-l_i),a_i-mid*l_i) ∑min(mid∗(ri−li),ai−mid∗li)。
另外需要特判,特判如下 ∑ l i > R {\sum}l_i>R ∑li>R或 ∑ r i < L {\sum}r_i<L ∑ri<L
的确是很有意思的二分
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
#define inf 0x7fffffff
//#define ll long long
//#define int long long
#define int __int128
//#define double long double
#define re int
#define void inline void
#define eps 1e-8
//#define mod 1e9+7
#define ls(p) p<<1
#define rs(p) p<<1|1
#define pi acos(-1.0)
#define pb push_back
#define P pair < int , int >
#define mk make_pair
using namespace std;
//const int mod=1e9+7;
//const int M=1e8+5;
//const int N=8e5+5;//?????????? 4e8
int k,L,R;
int l[800005],r[800005];
int a[800005];
int suml,sumr;
int ans;
template<typename T> inline T read()
{
T sum = 0, fg = 1; char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') fg = -1;
for (; isdigit(c); c = getchar()) sum = (sum << 3) + (sum << 1) + (c ^ 0x30);
return fg * sum;
}
void write(int x)
{
if(x==0) return;
write(x/10);
putchar(x%10+'0');
}
bool check(int mid)
{
for(re i=1;i<=k;i++) if(l[i]*mid>a[i]) return 0;
int cnt=0;
for(re i=1;i<=k;i++) cnt+=min(a[i]-mid*l[i],mid*(r[i]-l[i]));
return cnt>=(L-suml)*mid;
}
void solve()
{
// cin>>k>>L>>R;
k=read<int>();
L=read<int>();
R=read<int>();
for(re i=1;i<=k;i++) a[i]=read<int>();
for(re i=1;i<=k;i++) l[i]=read<int>(),r[i]=read<int>(),suml+=l[i],sumr+=r[i];
if(sumr<L||suml>R)
{
puts("0");
return;
}
// if(L<=suml&&suml<=R)
// {
// ans=1e18;
// for(re i=1;i<=k;i++) ans=min(ans,a[i]/l[i]);
// cout<<ans<<endl;
// return;
// }
int ll=0,rr=1e14;
while(ll<rr)
{
int mid=(ll+rr+1)>>1;
if(check(mid)) ans=mid,ll=mid;
else rr=mid-1;
}
write(ll);
// cout<<ll<<endl;
}
signed main()
{
int T=1;
// cin>>T;
for(int index=1;index<=T;index++)
{
// printf("Case %d:\n",index);
solve();
// puts("");
}
return 0;
}
/*
3 4
DDDS
WAAS
WAAA
*/