标签:cf535 le 零数 ll mid Tavas mt while Karafs
题意:
给定一个递增等差数列,每次操作可把不超过 \(m\) 个不同的位置减 1
\(q\) 次询问,每次 \(l,t,m\),输出用不超过 \(t\) 次操作能把 \([l,r]\) 变成 0 的最大 \(r\)
思路:
首先显然二分。然后怎么判断呢?结论是合法当且仅当 \(\sum a_i \le mt\) 且 \(\max a_i \le t\)
显然这是必要的。充分性也很好证:
若 \([l,r]\) 中有大于等于 \(m\) 个非零数,则最大值的数量至多 \(m\) 个(否则总和可能超过 \(mt\))。我们从大到小选 \(m\) 个数,把它们都减 1。注意这不会改变 \(\sum a_i \le mt\) 的关系。重复此操作直到下一种情况。
若非零数小于 \(m\) 个,那就把所有非零数减 1。显然这是可行的!
ll A, B, q, L, t, m;
bool ok(ll R) {
return A+B*(R-1) <= t &&
(A+B*(L-1)+A+B*(R-1))*(R-L+1)/2 <= t*m;
}
void sol() {
cin >> A >> B >> q;
while(q--) {
cin >> L >> t >> m;
ll l = L-1, r = 1e7;
while(l < r) {
ll mid = (l + r + 1) / 2;
if(ok(mid)) l = mid; else r = mid - 1;
}
cout << (l < L ? -1ll : l) << endl;
}
}
标签:cf535,le,零数,ll,mid,Tavas,mt,while,Karafs 来源: https://www.cnblogs.com/wushansinger/p/16366389.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。