[Explanations] [CF 1250J] The Parade

Face questions

Subject to the effect:

Given a \ (n-\) , the number of all soldiers were \ ([1, n] \ )

Given \ (a_i \) representative of a height of \ (I \) number of soldiers

You want these soldiers into \ (k \) line, the following two conditions are satisfied

  • An equal number of each row
  • The absolute value of the height difference between any two of the soldiers in the same row not more than 1

Q. You can choose the maximum number of soldiers into \ (k \) line

answer

Title monotone be bipartite

We half a \ (mid \) represents each row has \ (mid \) soldier

The first card was not difficult to equal height into line, highly unequal subdivision is optimal

Brief Proof: The above scheme can not be adjusted to the embodiment of the aspects, the result will not be worse

So now we are to look at how points are the best

We height \ (i + 1 \) and the \ (I \) up equivalent to the \ (I \) and the \ (i + 1 \) up

If you say \ (A_ +. 1 {I}> = a_i \% MID \) , we can be \ (a_ {i + 1} \) subtracting \ (a_i \% MOD \) , then \ (ANS \ ) plus one

Correctness:

First, if no \ (a_i \) remaining, and the remaining part of this pairing \ (a_ {i + 1} \) certainly keep themselves or \ (a_ {i + 2} \) paired

That is certainly the use of this part, if in his back and body, may cause not pair back

That

This part is always paired with the front pairing does not affect the back, because the latter did not change the total number of

With the latter pair might later affect the answer, because the total number changed

This shows that this pairing will not be worse

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
typedef long long ll;
const int N = 30005; 
using namespace std;

int T, n; 
ll k, a[N], b[N], ans, sum; 

template < typename T >
inline T read()
{
    T x = 0, w = 1; char c = getchar();
    while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * w; 
}

bool check(ll x)
{
    ll res = 0; b[1] = a[1]; 
    for(int i = 1; i <= n; i++)
    {
        res += b[i] / x;
        b[i + 1] = a[i + 1]; 
        if(b[i + 1] >= x - (b[i] % x))
            b[i + 1] -= x - (b[i] % x), res++; 
    }
    return res >= k; 
}

int main()
{
    T = read <int> ();
    while(T--)
    {
        ans = sum = 0; n = read <int> (), k = read <ll> ();
        for(int i = 1; i <= n; i++)
            sum += (a[i] = read <ll> ());
        a[n + 1] = 0; 
        ll l = 1, r = sum; 
        while(l <= r)
        {
            ll mid = (l + r) >> 1;
            if(check(mid)) ans = mid, l = mid + 1;
            else r = mid - 1; 
        }
        printf("%lld\n", 1ll * ans * k); 
    }
    return 0; 
}

Guess you like

Origin www.cnblogs.com/ztlztl/p/12000694.html