Idi na tekst

B3 - Zlatnici 2: Električni Bugalu

Vremensko ograničenje Memorijsko ograničenje
1500ms 256MB

Nastavak nikad nije dobar koliko i original. Stalno viđamo nastavke koji ne uspeju da razumeju zašto je original toliko voljen i ispadnu dosadni, standardni ili prosto loši. Naravno, mi nastojimo da promenimo to i zato vam predstavljamo silno isčekivani nastavak na kultni klasik prošlogodišnjeg ciklusa: "Zlatnici 2: Električni Bugalu"!

Kralj Mida pred sobom ima brojevnu pravu i na nekih N različitih celobrojnih koordinata ima po jedan zlatnik. On igra igru gde u jednom potezu može da premesti jedan zlatnik na susednu poziciju na brojevnoj pravoj (sa x ili na x+1 ili na x1), ali ni u jednom trenutku dva zlatnika ne smeju da se nađu na istom mestu. Mida želi da postavi da se zlatnici nalaze jedan do drugog, ali ne zna još tačno gde. Zato će razmotriti Q različitih scenarija za svoju igru. Svaki scenario će biti opisan jednim brojem x, i u tom scenariju će Midin cilj da bude da premesti zlatnike tako da se nalaze na različitim pozicijama iz skupa pozicija {x,x+1,,x+N1}. Svi scenariji su nezavisni, to jest, zlatnici uvek kreću sa istih pozicija.

Kralj Mida je od vas zatražio pomoć da nađete najmanji broj poteza da bi završio igru u svakom scenariju, jer ako bi vam on već znao odgovor na to pitanje, to i ne bi bio nešto dobar zadatak.

Opis ulaza

U prvom redu ulaza se nalazi prirodan broj N, broj zlatnika. U drugom redu se nalazi N prirodnih brojeva a1<a2<<aN u rastućem poretku, koji predstavljaju početne pozicije zlatnika. U trećem redu se nalazi prirodan broj Q, broj scenarija. U narednih Q linija se nalazi po jedan broj x kojim su opisani scenariji.

Opis izlaza

Na izlaz ispisati Q brojeva, gde i-ti predstavlja najmanji broj poteza da Mida završi igru u i-tom scenariju.

Ograničenja

  • 1N,Q200.000
  • 0<a1<a2<<aN109
  • 0<x109 za svaki upit

Test primeri su podeljeni u 4 disjunktne grupe:

  • U test primerima vrednim 10 poena: N=1.
  • U test primerima vrednim 10 poena: N,Q1000, ai100.000 i x100.000 za svaki scenario.
  • U test primerima vrednim 30 poena: ai=p+id, to jest početne pozicije zlatnika formiraju aritmetičku progresiju.
  • U test primerima vrednim 50 poena: Bez dodatnih ograničenja.

Primeri

Primer 1

Ulaz

2
2 4
2
5
2

Izlaz

5
1

Objašnjenje

U prvom scenariju, drugi zlatnik možemo da premestimo 2 mesta udesno (sa 4 na 6), a prvi zlatnik 3 mesta udesno (sa 2 na 5) i time smo završili igru. U drugom scenariju, dovolljno je premestiti drugi zlatnik jedno mesto ulevo.

Autor Tekst i test primeri Analiza rеšenja Testiranje
Pavle Martinović Pavle Martinović Mladen Puzić Aleksa Plavšić

Rešenje za N=1:

Imamo samo jedan zlatnik koji je u svakom scenariju potrebno dovesti na odgovarajuću poziciju. Da bismo sa pozicije a1 došli do pozicije x potrebno je |a1x| poteza. Vremenska složenost je O(N+Q).

Rešenje za N,Q1000 i ai,x105:

Pošto nije dozvoljeno da se dva zlatnika nalaze na istoj poziciji, takođe nije moguće da se dva zlatnika mimoiđu. Samim tim, zlatnik sa pozicije a1 će završiti na poziciji x, zlatnik sa pozicije a2 na x+1, ..., zlatnik sa pozicije aN na x+N1. Pošto će u svakom trenutku postojati zlatnik koji može da se približi svojoj krajnjoj poziciji, rešenje je |a1x|+|a2x1|+...+|aNxN+1|, odnosno i=0N1|ai+1xi|. Pošto su N i Q mali, možemo ručno izračunati ovu sumu za svaki scenario. Vremenska složenost je O(NQ).

Rešenje za ai=p+id:

Primetimo da važi |ai+1ix|=x(ai+1i) ako ai+1ix, a |ai+1ix|=ai+1ix u suprotnom. Pošto je niz ai rastući, za prvih nekoliko (potencijalno nula) žetona važiće prvi slučaj, dok će za ostale važiti drugi slučaj. Označimo sa k indeks poslednjeg žetona za koji važi ai+1ix (ako ne postoji takav žeton onda k=0, inače k=i+1). Primetimo da onda važi i=0N1|ai+1xi|=i=0k1(x(ai+1i))+i=kN1((ai+1i)x). Odnosno rešenje je kxi=0k1(ai+1i)+i=kN1(ai+1i)(Nk)x. Kada znamo k, sume iz formule možemo naći prefiksnim sumama. Sve ovo u stvari znači da ćemo nekoliko prvih novčića pomerati udesno, dok ćemo ostale pomerati ulevo.

Ostalo nam je samo da nađemo k. Ako ai=p+id, možemo uzeti p=a1 i d=a2a1 (ako N2). Tražimo najveće k=i+1 tako da važi ai+1ix, tj. p+(i+1)dix. Važi i+1x+ipd. Samim tim važi k=x+ipd, gde je x ceo deo od x. Vremenska složenost je O(N+Q).

Glavno rešenje:

Jedina razlika ovog rešenja i rešenja za prethodnu grupu test primera je nalaženje k. Za 100 poena potrebno je da koristimo binarnu pretragu nad nizom ai+1i (tražimo prvo i za koje je to veće od x). Vremenska složenost je O(N+QlogN).

03_zlatnici2.cpp
#include <bits/stdc++.h>
#define MAXN 200007
using namespace std;
long long a[MAXN],pr[MAXN],su[MAXN];
long long formula(long long x,long long k)
{
    return x*k+(k*(k-1))/2;
}
int binarna(int l,int r,long long x)
{
    if(l==r) return l;
    int s=(l+r+1)/2;
    if(a[s]-s<x) return binarna(s,r,x);
    return binarna(l,s-1,x);
}
int main()
{   int n,q;
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%lld",&a[i]);
    pr[0]=a[0];
    for(int i=1;i<n;i++) pr[i]=pr[i-1]+a[i];
    su[n]=0;
    for(int i=n-1;i>=0;i--) su[i]=su[i+1]+a[i];
    scanf("%d",&q);
    while(q--)
    {
        long long x;
        scanf("%lld",&x);
        if(a[0]>=x) {printf("%lld\n", pr[n-1]-formula(x,n)); continue;}
        int t=binarna(0,n-1,x);
        printf("%lld\n",(formula(x,t+1)-pr[t])+(su[t+1]-formula(x+t+1,n-t-1)));
    }
}