Znalezienie problemu w programie operującym na drzewach przedziałowych

0

witam pomoglby ktos w znalezieniu defektu mojego programu i dlaczego nie mam stowy? wszystko sobie analizowalem, typy zmiennych sa ok i dlatego nie wm co moze byc zle.
kod:

#include <iostream>
#include <algorithm>

using namespace std;

int n, m, q;

pair <int, int> arr[1100000];

void buildArr() {
	q = (1 << 19) - 1;
	for (int i = q + 1; i <= q + n; i ++) {
		cin >> arr[i].first;
		arr[i].second = i - q;
	}
	for (int i = q; i >= 1; i --)
		arr[i] = max(arr[i * 2], arr[i * 2 + 1]);
}

void update(int a, int b) {
	arr[a + q].first += b;
	for (int i = (a + q) / 2; i > 1; i /= 2)
		arr[i] = max(arr[i * 2], arr[i * 2 + 1]);
}

int maxAB(int a, int b) {
	a += q; b += q;
	pair <int, int> maxPr = {0, 0};
	while (a <= b) {
		maxPr = max(maxPr, max(arr[a], arr[b]));
		a = (a + 1) / 2;
		b = (b - 1) / 2;
	}
	return maxPr.second;
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int a, b, k;
	cin >> n >> m;
	buildArr();
	while (m --) {
		cin >> k;
		while (k --) {
			cin >> a >> b;
			update(a, b);
		}
		cin >> a >> b;
		cout << maxAB(a, b) << '\n';
	}
}

zadanie:
https://docdro.id/lplKOih <- PDF
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Około 70% testów przechodzi ze znakomitym czasem. Reszta to co widać:
3 wiersz 1773: wczytano '87', a oczekiwano '101'
9 wiersz 2148: wczytano '28912', a oczekiwano '55555'
10 wiersz 2148: wczytano '139178', a oczekiwano '55555'

4

Jak na początkującego kod wygląda dość dobrze. Jest podział na funkcje, które nie są za duże, są włąściwe wcięcia. Częściowo oddzieliłeś operacje IO od logiki

Negatywne części:

  • IO pojawia się jednak w innym miejscu: cin >> arr[i].first; w bud (nie wiadomo co oznacza ten symbol - popraw nazwę). Jak trzyma się oddzielnie IO od obliczeń to łatwo zautomatyzować testowanie kodu.
  • unikaj zmiennych globalnych
  • nie używaj std::pair to zaciemnia kod (utrudnia czytanie). Zdefiniuj odpowiednie strukturę, z nazwami, które będą pomagać zrozumieć kod. std::pair przeznaczone jest gdy piszę się szablony - dla zaawansowanego poziomu umiejętności C++.
  • nie ma treści zadania (była próba z obrazkami), ergo nie potrafię powiedzieć co ten kod ma robić
0

juz wszystko dziala, trzeba bylo zamienic typ arr[].first z int'a na long long'a

2
polandonion napisał(a):

juz wszystko dziala, trzeba bylo zamienic typ arr[].first z int'a na long long'a

No to z tego wynika, że testy są niezgodne z treścią zadania, bo zakres int to 2 miliardy, a prędkości początkowe i ulepszenia miały być mniejsze od miliona, a jedyną operację jaką wykonujesz to dodawanie i max.

sam.pdf | DocDroid

W kolejnym wierszu znajduje się n liczb, gdzie i-ta liczba to vi (1 ≤ vi ≤ 1 000 000), czyli prędkość
samochodu o i-tym numerze.
W kolejnych wierszach znajdują się opisy kolejnych k wyścigów. Każdy taki opis składa się z: wartości xi
(0 ≤ x1 +x2 +...+xn ≤ 300000), czyli liczby ulepszeń przed i-tym wyścigiem, xi wierszy zawierających
dwie liczby: si, di (1 ≤ sin, 0 ≤ di ≤ 1 000 000)

Swoją drogą nie ogarniam jak ty zorganizowałeś sobie te indeksy.
Ja naskrobałem coś takiego:

template <typename T>
T rounUpToPow2(T x)
{
    T r = 1;
    while (r < x)
        r <<= 1;
    return r;
}

struct Car {
    int maxSpeed = 0;
    int raceNumber = 0;
};

bool operator<(const Car& a, const Car& b)
{
    return a.maxSpeed < b.maxSpeed;
}

class CarCompetitions {
    std::vector<Car> intervalTree;
    size_t n;

    size_t parentIndex(size_t i) const
    {
        return n + i / 2;
    }

    void updateIntervalFrom(size_t i)
    {
        auto next = parentIndex(i);
        while (next < intervalTree.size() && intervalTree[next] < intervalTree[i]) {
            intervalTree[next] = intervalTree[i];
            i = next;
            next = parentIndex(i);
        }
    }

    void initRanges()
    {
        intervalTree.reserve(2 * n - 1);
        intervalTree.resize(n);
        for (size_t i = 0; i < n - 1; ++i) {
            intervalTree.emplace_back(std::max(intervalTree[2 * i], intervalTree[2 * i + 1]));
        }
    }

    static size_t raceNumberToIndex(int x) 
    {
        return x - 1;
    }

public:
    CarCompetitions(std::vector<Car> competitors)
        : intervalTree { std::move(competitors) }
        , n { rounUpToPow2(intervalTree.size()) }
    {
        initRanges();
    }

    void upgradeCar(int raceNumber, int extraSpeed)
    {
        auto& carToUpagrade = intervalTree[raceNumber - 1];
        carToUpagrade.maxSpeed += extraSpeed;
        updateIntervalFrom(raceNumber - 1);
    }

    Car bestCarFromToIndexes(size_t a, size_t b) const
    {
        Car best;
        while (a < b) {
            best = std::max(best, intervalTree[a]);
            best = std::max(best, intervalTree[b]);
            a = parentIndex(a + 1);
            b = parentIndex(b - 1);
        }
        best = std::max(best, intervalTree[a]);
        return best;
    }

    Car bestCarFromTo(int a, int b) const
    {
        return bestCarFromToIndexes(raceNumberToIndex(a), raceNumberToIndex(b));
    }
};

https://godbolt.org/z/WdfYo5Tas

1 użytkowników online, w tym zalogowanych: 0, gości: 1