Pagini recente » Cod sursa (job #3318293) | Cod sursa (job #475587) | Cod sursa (job #3327271) | Cod sursa (job #3170555) | Cod sursa (job #3345262)
#include <fstream>
#include <cmath>
#include <algorithm>
using namespace std;
// Deschidem fișierele folosind fstream (fin și fout)
ifstream fin("arbint.in");
ofstream fout("arbint.out");
int valoare[100005]; // Vectorul cu numerele noastre
int maxim_cutie[400]; // "Eticheta" cu maximul pentru fiecare cutie
int N,M;
int cat_de_mare_e_cutia; // Aceasta este valoarea sqrt(N)
int main()
{
// 1. Citim N și M
fin>>N>>M;
// 2. Calculăm cât de mare să fie o "cutie"
cat_de_mare_e_cutia=sqrt(N);
// 3. Citim numerele și, în același timp, pregătim "eticheta" fiecărei cutii
for(int i=1;i<=N;i++)
{
fin>>valoare[i];
// Aflăm în ce cutie trebuie să punem numărul i
int nr_cutie=(i-1)/cat_de_mare_e_cutia+1;
// Dacă e primul element din cutie, el e maximul momentan
// Dacă nu, verificăm dacă e mai mare decât ce aveam deja în cutie
if(i%cat_de_mare_e_cutia== 1 || i==1)
{
maxim_cutie[nr_cutie]=valoare[i];
}
else
{
if(valoare[i]>maxim_cutie[nr_cutie])
{
maxim_cutie[nr_cutie]=valoare[i];
}
}
}
// 4. Procesăm cele M operații
for(int k=1;k<=M;k++)
{
int tip,X,Y;
fin>>tip>>X>>Y;
if(tip==1)
{
// --- UPDATE: Schimbăm valoarea de la poziția X cu numărul Y ---
valoare[X]=Y;
int nr_cutie=(X - 1)/cat_de_mare_e_cutia+1;
// Când schimbăm un număr, trebuie să recalculăm maximul din cutia lui
int inceput=(nr_cutie - 1)*cat_de_mare_e_cutia+1;
int sfarsit=nr_cutie*cat_de_mare_e_cutia;
if(sfarsit>N)
sfarsit=N;
maxim_cutie[nr_cutie]=-1; // Resetăm eticheta
for(int j=inceput;j<=sfarsit;j++)
{
if(valoare[j]>maxim_cutie[nr_cutie])
{
maxim_cutie[nr_cutie]=valoare[j];
}
}
}
else
{
// --- QUERY: Căutăm maximul între poziția X și poziția Y ---
int maxim_final=-1;
int cutia_start=(X - 1)/cat_de_mare_e_cutia+1;
int cutia_final=(Y - 1)/cat_de_mare_e_cutia+1;
if(cutia_start==cutia_final)
{
// Dacă X și Y sunt în aceeași cutie, căutăm normal între ele
for(int j=X;j<=Y;j++)
{
if(valoare[j]>maxim_final)
maxim_final=valoare[j];
}
}
else
{
// Avem 3 părți de verificat:
// Partea 1: De la X până la finalul cutiei în care se află X
int sfarsit_cutie_X=cutia_start*cat_de_mare_e_cutia;
for(int j=X;j<=sfarsit_cutie_X;j++)
{
if(valoare[j]>maxim_final)
maxim_final=valoare[j];
}
// Partea 2: Cutiile "pline" de la mijloc (aici e viteza!)
for(int c=cutia_start+1;c<cutia_final;c++)
{
if(maxim_cutie[c]>maxim_final)
maxim_final=maxim_cutie[c];
}
// Partea 3: De la începutul cutiei lui Y până la poziția Y
int inceput_cutie_Y=(cutia_final - 1)*cat_de_mare_e_cutia+1;
for(int j=inceput_cutie_Y;j<=Y;j++)
{
if(valoare[j]>maxim_final)
maxim_final=valoare[j];
}
}
fout<<maxim_final<<"\n";
}
}
return 0;
}