day49-刘肖
作者:互联网
T1 CF505E Mr. Kitayuta vs. Bamboos
- 给定 n 个数 \(h_{ 1 \dots n}\)。
- 你需要进行 m 轮操作,每轮操作为 k 次修改,每次修改可以选择一个数 \(h_i\) 修改为 \(\max(h_i - p, 0)\)。
- 每轮操作后每个 \(h_i\) 将会被修改为 \(h_i + a_i\)。
- 你需要最小化最终 \(h_{1 \dots n}\) 中的最大值。
- \(n \le 10^5\),\(m \le 5 \times 10^3\) $ k≤10$。
solution
首先二分答案,之后反着考虑,考虑这些竹子是每天减少\(a_i\),你可以给k个拔高\(p\) , 最后,要让最小的尽可能的大,也就是所有的竹子的高度都要$ >= h_i$ , 维护一个堆,每次把最可能变成0的加进去即可。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
#define int long long
inline int read()
{
register int x = 0 , f = 0; register char c = getchar();
while(c < '0' || c > '9') f |= c == '-' , c = getchar();
while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48) , c = getchar();
return f ? -x : x;
}
int n , m , k , p;
int h[N] , a[N] , t[N];
struct node
{
int d , id;
bool operator < (const node &A) const { return d > A.d; }
};
priority_queue<node> q;
bool check(int mid)
{
while(q.size()) q.pop();
for(int i = 1 ; i <= n ; ++i)
{
t[i] = mid;
if(t[i] - a[i] * m < h[i]) q.push((node){t[i] / a[i] , i});
}
for(int i = 1 ; i <= m ; ++i)
for(int j = 1 ; j <= k ; ++j)
{
if(q.empty()) return true;
int d = q.top().d , id = q.top().id; q.pop();
if(d < i) return false;
t[id] += p; if(t[id] - a[id] * m < h[id]) q.push((node){t[id] / a[id] , id});
}
return q.empty();
}
signed main()
{
n = read(); m = read(); k = read(); p = read();
for(int i = 1 ; i <= n ; ++i) h[i] = read() , a[i] = read();
int l = 0 , r = 0 , mid , ans = 0;
for(int i = 1 ; i <= n ; ++i) r = max(r , h[i] + a[i] * m);
while(l <= r)
{
mid = (l + r) >> 1;
if(check(mid)) ans = mid , r = mid - 1; else l = mid + 1;
}
cout << ans << '\n'; return 0;
}
标签:10,le,int,mid,修改,while,day49,刘肖 来源: https://www.cnblogs.com/R-Q-R-Q/p/13139750.html