TAKMIČENJA IZ PROGRAMIRANJA


Sva pitanja, predloge ili primedbe u vezi sa takmičenjima iz programiranja možete slati na e-mail:

tak.prog@gmail.com

U toku perioda za žalbe, sve žalbe možete slati na ovaj isti e-mail.

baloni.cpp    1,982 b      izvorni kod rešenja
baloni.tests.rar    3,143,470 b      test primeri

zadatak: Baloni

Mali Đura je dobio sledeći zadatak. Njemu se donose prazni baloni i baloni sa vodom. Kad mu se donese prazan balon, postavlja se pitanje iz koliko najviše donetih balona sa vodom do sada može da istrese svu vodu u upravo doneti prazan balon. Da bi opisali zadatak koji je postavljen malom Đuri, definisaćemo dve operacije

  • N v - donet je nov balon u kome se nalazi v litara vode
  • Q v - donet je nov balon zapremine v litara, ali prazan. U tom momentu, mali Đura treba da odgovori iz koliko najviše do sada donetih balona može da se prespe voda u trenutno donešeni
Napomena. Kada se donese prazan balon, baloni iz kojih može da se prespe voda se ne prazne, samo se daje odgovor koliko najviše može da se isprazni.

Ulaz:

(Ulazni podaci se nalaze u datoteci baloni.in) U prvom redu se nalazi prirodan broj M (1 ≤ M ≤ 100.000) koji predstavlja broj operacija. U svakom od narednih M redova se nalaze operacije oblika C v, gde C {N, Q}. Ako C = N, tada 1 ≤ v ≤ 200.000. Ako C = Q, tada 1 ≤ v ≤ 100.000.000.

Izlaz:

(Izlazne podatke upisati u datoteku baloni.out) Za svaku operaciju oblika Q v, redom, u jedan red ispisati koliko najviše do sada donešenih balona sa vodom može da se isprazni u dati balon.

Primer 1:

baloni.in      baloni.out
9
Q 10
N 3
Q 10
N 7
Q 10
N 2
Q 10
N 3
Q 10
        
0
1
2
2
3

Objašnjenje.

Nakon donošenja prvog praznog balona, ne postoji ni jedan donet balon sa vodom, te nije moguće ni jedan presuti u isti. Nakon donošenja poslednjeg praznog balona u njega je moguće presuti vodu iz balona zapremina 3, 2 i 3, što je i najviše u ovom slučaju.

Primer 2:

baloni.in      baloni.out
10
N 5
N 8
N 1
Q 20
N 11
Q 8
N 1
N 2
Q 31
N 12
        
3
2
6
fajl: baloni.cpp
/*
  Author: Slobodan Mitrovic
  e-mail: boba5555@gmail.com
  date: 25.05.2009.
  Complexity: O(m log max_v) - in this case, max_v = 200000
*/
#include <iostream>
#include <cstdio>
#define ffor(_a,_f,_t) for(int _a=(_f),__t=(_t);_a<__t;_a++)
#define all(_v) (_v).begin() , (_v).end()
#define sz size()
#define pb push_back
#define SET(__set, val) memset(__set, val, sizeof(__set))
#define FOR(__i, __n) ffor (__i, 0, __n)

using namespace std;

const int MAXVAL = 200002;
const int HIGHEST_BIT = 1 << 17;

int bit[MAXVAL];
long long bitWeight[MAXVAL]; // 100000 * 200000 > 2^32

void update(int idx){
  int weight = idx;
  while (idx < MAXVAL){
    bit[idx]++;
    bitWeight[idx] += weight;
    idx += (idx & -idx);
  }
}

struct mpair{
  long long a, b;
  mpair(){
  }

  mpair(long long _a, long long _b){
    a = _a;
    b = _b;
  }
};

mpair read(int idx){
  long long ret = 0, retW = 0;
  while (idx){
    ret += bit[idx];
    retW += bitWeight[idx];
    idx -= (idx & -idx);
  }

  return mpair(ret, retW);
}

int find(int cumFre){
  int ret = -1, idx = 0, bitMask = HIGHEST_BIT;

    while ((bitMask != 0) && (idx < MAXVAL)){
        int tIdx = idx + bitMask;
        if (tIdx < MAXVAL){
          if (cumFre > bitWeight[tIdx]){
             idx = tIdx;
             cumFre -= bitWeight[tIdx];
          }
          else
        ret = tIdx;
    }
        bitMask >>= 1;
    }

    return ret;
}

int main(){
    freopen("baloni.in", "rt", stdin);
    freopen("baloni.out", "wt", stdout);
    int M, v, ret, canTake, cntOpN = 0, idx;
    mpair rr;
    char op;
    scanf("%d", &M);
    SET(bit, 0);
    SET(bitWeight, 0);
    FOR (i, M){
    scanf("\n%c %d", &op, &v);
    if (op == 'N'){
      update(v);
      cntOpN++;
    }
    else{
      idx = find(v);
      if (idx == -1)
        printf("%d\n", cntOpN);
      else{
        rr = read(idx - 1);
        ret = rr.a;
        v -= rr.b;
        ret += v / idx;
        printf("%d\n", ret);
      }
    }
  }
  return 0;
}