C. Make It Equal
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
There is a toy building consisting of nn towers. Each tower consists of several cubes standing on each other. The ii-th tower consists of hihicubes, so it has height hihi.
Let's define operation slice on some height HH as following: for each tower ii, if its height is greater than HH, then remove some top cubes to make tower's height equal to HH. Cost of one "slice" equals to the total number of removed cubes from all towers.
Let's name slice as good one if its cost is lower or equal to kk (k≥nk≥n).
Calculate the minimum number of good slices you have to do to make all towers have the same height. Of course, it is always possible to make it so.
Input
The first line contains two integers nn and kk (1≤n≤2⋅1051≤n≤2⋅105, n≤k≤109n≤k≤109) — the number of towers and the restriction on slices, respectively.
The second line contains nn space separated integers h1,h2,…,hnh1,h2,…,hn (1≤hi≤2⋅1051≤hi≤2⋅105) — the initial heights of towers.
Output
Print one integer — the minimum number of good slices you have to do to make all towers have the same heigth.
Examples
input
Copy
5 5 3 1 2 2 4
output
Copy
2
input
Copy
4 5 2 3 4 5
output
Copy
2
Note
In the first example it's optimal to make 22 slices. The first slice is on height 22 (its cost is 33), and the second one is on height 11 (its cost is 44).
题意:
有n个柱子, 第i个柱子高度hi, 有一个代价上限k, 每次操作可以选择一个高度x,使得hi 变成min(hi,x)
但是要求代价 sum(hi-min(hi,x)) <=k;
问最少需要几次x 使得hi全部相等.
起初想用 贪心+二分来做,但是,这个地方的二分太难调了, 一直TLE3..
难受
结束后, 想想, 其实可以这样做.
从最高出开始贪心, 只要sum < k 就 继续往下 . 知道某个位置 时 更新.
加的值必须O(1) 查询, 那么可以用 类似前缀和的思想. 统计每一高度的数目, 然后累计.
代码:
#include <bits/stdc++.h>
#include <stdio.h>
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,a,n) for(int i=n;i>=a;i--)
typedef long long ll;
const int maxn = 2e5+10;
const int mod =1e9+7;
const int inf = 0x3f3f3f3f;
using namespace std;
ll a[maxn];
ll n,k;
ll cot[maxn];
int main(int argc, char const *argv[])
{
cin>>n>>k;
ll ma = -inf,mi = inf;
rep(i,1,n)
{
cin>>a[i];
cot[a[i]]++;
ma = max(ma,a[i]);
mi = min(mi,a[i]);
}
for (int i = ma; i>=1; --i)
cot[i] += cot[i + 1];
ll ans = 0;
ll now = 0;
for(int i = ma; i > mi ;i--)
{
if( now + cot[i] > k)
{
ans++;
now = 0;
}
now+= cot[i];
}
if (now) ans++;
cout<<ans<<endl;
return 0;
}