Cod sursa(job #1485618)

Utilizator geniucosOncescu Costin geniucos Data 12 septembrie 2015 15:24:16
Problema A+B Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.27 kb
#include<cstdio>
#include<algorithm>

using namespace std;

int sum, v[1000009], N, sum4[1000009], Ras2, Ras, plst, pldr;
long long INF, L, R, St, K, mini, maxi;

/*struct ceva
{
    long long v, r;
}a[1000009];*/

long long sum3 (int i, long long St, long long maxdif)
{
    return 1LL * sum4[i] * St;
}

long long sum2 (int i, long long St, long long maxdif)
{
    return 1LL * sum4[i] * maxdif;
}

long long Cost (long long V, long long maxdif, long long St)
{
    int p, u, mij, ras = 0, ras2 = 0;
    p = 1;
    u = N;
    while (p <= u)
    {
        mij = (p + u) >> 1;
        if (1LL * v[mij] * (St + maxdif) <= V) ras = mij, p = mij + 1;
        else u = mij - 1;
    }
    Ras = ras;
    long long ans = sum2 (ras, St, maxdif);
    p = 1;
    u = N;
    while (p <= u)
    {
        mij = (p + u) >> 1;
        if (1LL * v[mij] * St <= V) ras2 = mij, p = mij + 1;
        else u = mij - 1;
    }
    Ras2 = ras2;
    ans = (long long) ans + 1LL * (ras2 - ras) * V - (sum3 (ras2, St, maxdif) - sum3 (ras, St, maxdif));
    return ans;
}

long long getv (int pos, long long maxdif, long long St, long long Mij)
{
    long long V, r;
    V = 1LL * v[pos] * St;
    r = 1LL * v[pos] * (St + maxdif);
    if (r <= Mij) return r+ (pos >= plst && pos <= pldr);
    if (V <= Mij) return Mij + (pos >= plst && pos <= pldr);
    return V + (pos >= plst && pos <= pldr);
}

void proces (long long maxdif, long long pasi, long long St, bool af)
{
//    for (int i=1; i<=N; i++)
  //      sum3[i] = sum3[i-1] + a[i].v, sum2[i] = sum2[i-1] + a[i].r - a[i].v;
    long long p, u, mij, ras;
    p = 1LL * v[1] * St;
    u = 1LL * v[N] * (St + maxdif);
    while (p <= u)
    {
        mij = (long long) p + (long long) (u - p) / 2LL;
        //if (St == 5 && maxdif == 3)
            //maxdif = 3;
        long long cost = Cost (mij, maxdif, St);
        if (cost <= pasi) ras = mij, p = mij + 1;
        else u = mij - 1;
    }
    mij = ras;
    long long cost = Cost (mij, maxdif, St);
/*    for (int i=1; i<=N; i++)
    {
        if (a[i].r <= mij) cost += a[i].r - a[i].v, a[i].v = a[i].r;
        else
        if (a[i].v <= mij) cost += mij - a[i].v, a[i].v = mij;
    }*/
    pasi -= cost;
    //for (int i=1; i<=N; i++)
      //  i
    //pana la Ras, inclusiv e full
    plst = Ras + 1;
    pldr = plst + pasi - 1;
    mini = getv (1, maxdif, St, mij), maxi = getv (N, maxdif, St, mij);long long curr;
        if (af)
    {
        for (int i=1; i<=N; i++)
            printf ("%lld ", getv (i, maxdif, St, mij));
    }
    curr = getv (plst, maxdif, St, mij);
    if (curr < mini) mini = curr;
    if (curr > maxi) maxi = curr;
    curr = getv (pldr, maxdif, St, mij);
    if (curr < mini) mini = curr;
    if (curr > maxi) maxi = curr;
}

bool ok (long long St, long long maxdif)
{
    long long L = 0, R = 0;
    if (K / sum < St) return 0;
    L = 1LL * sum * St;
    if (K / sum >= St + maxdif)
    {
        R = 1LL * sum * (St + maxdif);
        if (R < K) return 0;
    }
    //if (L > K || R < K) return 0;
//    for (int i=1; i<=N; i++)
  //      a[i].v = 1LL * v[i] * St, a[i].r = 1LL * v[i] * (St + maxdif);
    proces (maxdif, K - L, St, 0);
    /*for (int i=1; i<=N; i++)
    {
        if (a[i].v < mini) mini = a[i].v;
        if (a[i].v > maxi) maxi = a[i].v;
    }*/
    return (maxi - mini <= maxdif);
}

long long F (long long i)
{
    long long p, u, mij, ras = -1;
    p = 0, u = K - i;
    while (p <= u)
    {
        mij = (long long) p + (long long) (u - p) / 2LL;
        if (ok (i, mij)) ras = mij, u = mij - 1;
        else p = mij + 1;
    }
    if (ras == -1) return INF;
    return ras;
}

long long ternar_search (long long st, long long dr)
{
    long long p, u, mij, ras;
    p = st;
    u = dr;
    while (p <= u)
    {
        mij = (long long) p + (long long) (u - p) / 2LL;
        long long C1, C2;
        C1 = F (mij), C2 = F (mij + 1);
        if (C1 < C2) ras = mij, u = mij - 1;
        else p = mij + 1;
    }
    St = ras;
    return F (ras);
}

void Read (int &x);
void Read2 (long long &x);

int main ()
{
freopen ("mostenire.in", "r", stdin);
freopen ("mostenire.out", "w", stdout);

INF = 1LL << 60;
Read (N), Read2 (K);
for (int i=1; i<=N; i++)
    Read (v[i]), sum += v[i];
for (int i=1; i<=N; i++)
    sum4[i] = sum4[i-1] + v[i];
//for (long long i = 0; i<=K/sum; i++)
 // printf ("%lld\n", F (i));
//F (5);
//return 0;
L = ternar_search (0, K / sum);
printf ("%lld\n", L);
int maxdif = L;
L = 1LL * sum * St;
//for (int i=1; i<=N; i++)
  //  a[i].v = 1LL * v[i] * St, a[i].r = 1LL * v[i] * (St + maxdif);
proces (maxdif, K - L, St, 1);
/*for (int i=1; i<=N; i++)
    printf ("%lld ", a[i].v);
printf ("\n");*/
return 0;
}

#define maxl 100000
int pos = maxl - 1;
char sir[maxl];

void Next ()
{
    if (++pos == maxl)
        fread (sir, 1, maxl, stdin), pos = 0;
}

void Read (int &x)
{
    for (;sir[pos] < '0' || sir[pos] > '9'; Next ()) ;
    for (x = 0; sir[pos] >= '0' && sir[pos] <= '9'; Next ()) x = x * 10 + sir[pos] - '0';
}

void Read2 (long long &x)
{
    for (;sir[pos] < '0' || sir[pos] > '9'; Next ()) ;
    for (x = 0; sir[pos] >= '0' && sir[pos] <= '9'; Next ()) x = (long long) 1LL * x * 10 + sir[pos] - '0';
}