Cod sursa(job #1485910)

Utilizator enedumitruene dumitru enedumitru Data 13 septembrie 2015 12:53:11
Problema Buline Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.61 kb
#include<fstream>
#include<cstdlib>
using namespace std;
ifstream f("buline.in"); ofstream g("buline.out");
int x[400001];
int main()
{   int n,i,sc,ic,smax,im,sfm,culoare,stot=0,smax2,sfmin,imin,smin;
    f>>n;
    for(i=1;i<=n;i++)
    {   f>>x[i]>>culoare;
        if(culoare==0) x[i]=-x[i];
        x[n+i]=x[i];
        stot+=x[i];
    }
    sc=smax=x[1];
    ic=im=sfm=1;
    for(i=2;i<=n;i++)
    {   if(sc+x[i]<x[i]) {sc=x[i]; ic=i;} else sc=sc+x[i];
        if(sc>smax) {smax=sc; im=ic; sfm=i;}
    }
    sc=smin=x[1];
    ic=imin=sfmin=1;
    for(i=2;i<=n;i++)
    {   if(sc+x[i]>x[i]) {sc=x[i]; ic=i;} else sc=sc+x[i];
        if(sc<smin) {smin=sc; imin=ic; sfmin=i;}
    }
    smax2=stot-smin;
    if(smax>smax2) g<<smax<<' '<<im<<' '<<sfm-im+1<<'\n';
        else g<<smax2<<' '<<(sfmin+1)%n<<' '<<n-(sfmin-imin+1)<<'\n';
    g.close(); return 0;
}/*
Problema este o variatie a unei probleme clasice: dandu-se un sir de N numere intregi sa se determine
 o secventa de suma maxima. Singura modificare este ca in aceasta problema sirul este circular.
 In prima parte a solutiei nu vom lua in considerare faptul ca sirul este circular.
Pentru a rezolva problema pentru un sir normal exista o solutie clasica O(N).
 Se calculeaza pentru fiecare i secventa de suma maxima care se termina
 cu elementul i: este fie secventa de suma maxima care se termina la elementul i-1,
  la care se adauga elementul i, fie doar elementul i.
  O scurta descriere in pseudocod a acestui algoritm:

s = smax = 0;
pentru i = 1, n executa
   s = max(s+A[i], A[i]);
   smax = max(smax, s);
sfarsit pentru
Vom trata acum si faptul ca sirul este circular.
Astfel, trebuie verificate si secventele de forma i,i+1,...N-1,N,1,2,...j-1,j.
Pentru a realiza acest lucru eficient precalculam un sir de sume partiale
Si = A1 + A2 + ... + Ai = Si-1+Ai si un al doilea sir Ti = max(S1, S2,..., Si) = max(Ti-1, Si).
Pentru un i fixat, cea mai buna secventa de forma i,i+1,...N-1,N,1,2,...j-1,j se poate calcula in O(1)
 astfel: Ti-1+SN-Si-1.
Un alt mod de a verifica secventele de forma i,i+1,...N-1,N,1,2,...j-1,j este
daca observam ca suma acestei secvente este de fapt suma tuturor elementelor din care se
scade secventa j+1, j+2, ... i-2, i-1.
Astfel ne intereseaza o secventa de suma minima pe care sa o scadem din suma totala.
Aceasta se poate determina cu o mica modificare a alogirtmului pentru suma maxima sau
 inmultind elementele cu -1 si cautand o secventa de suma maxima.
Complexitatea rezolvarii este O(N), iar pentru reconstituirea solutiei sunt
necesare doar cateva variabile aditionale pentru pozitie si lungime.
*/