Реши задачу на c++. Вам надоело заниматься олимпиа...
Создано: 16 августа 2025 г.
Отвечено с использованием GPT-5 Thinking от Chat01
Создано: 16 августа 2025 г.
Отвечено с использованием GPT-5 Thinking от Chat01
Реши задачу на c++.
Вам надоело заниматься олимпиадным программированием, поэтому было решено посвятить
оставшуюся часть жизни работе в саду.
Есть n яблонь, пронумерованных от 1 до n. Изначально (день 0) на деревьях ничего нет. Каждый
день на i-й яблоне вырастает i яблок.
Вы q раз хотите собрать урожай — в di-й день будут собраны все яблоки с деревьев на отрезке
[li
, ri
].
Вам стало интересно, а сколько денег вы сможете заработать на продаже фруктов. Для этого
после каждого сбора урожая нужно знать, сколько яблок вы собрали.
Формат входных данных
В первой строке дано число n (1 <= n <= 10^18) — количество яблонь.
На второй строке находится число q (1 <= q <= 2 · 10^5
) — количество раз, которое вы соберете
урожай.
Следующие q строк описывают сборы урожая. В i-й из них даны числа di
, li
, ri (1 <= li <= ri <= n,
1 <= di <= 10^18).
Гарантируется, что последовательность di возрастает.
Формат выходных данных
Выведите q строк. В i-й из них сообщите, сколько яблок будет собрано во время i-го сбора урожая
по модулю 998244353.
в этой задаче у каждого дерева хранится день последнего сбора (изначально 0).
Если в день собираем на отрезке , то урожай равен
Первое слагаемое считаем формулой суммы арифм. прогрессии, второе — если поддерживать разбиение на непересекающиеся отрезки с одинаковым значением . Тогда каждый запрос: «разбить» карту в точках и , пробежать отрезки внутри , посчитать вклад, стереть их и записать новый отрезок со значением . Амортизированно это на запрос, где — число затронутых отрезков (в сумме ).
Ниже — аккуратная реализация на C++ с 64-битными числами и модулем .
cpp#include <bits/stdc++.h> using namespace std; using int64 = long long; const long long MOD = 998244353; const long long INV2 = (MOD + 1) / 2; // 2^{-1} mod MOD struct Node { long long r; // right boundary of segment long long val; // last harvest day for this segment }; inline long long addmod(long long a, long long b) { long long s = a + b; if (s >= MOD) s -= MOD; return s; } inline long long submod(long long a, long long b) { long long s = a - b; if (s < 0) s += MOD; return s; } inline long long mulmod(long long a, long long b) { return (long long)((__int128)a * b % MOD); } // T(x) = 1 + 2 + ... + x (mod MOD) inline long long tri(unsigned long long x) { unsigned long long xm = x % MOD; unsigned long long xp1 = (x + 1) % MOD; return mulmod((long long)xm, mulmod((long long)xp1, (long long)INV2)); } // S(l,r) = l + ... + r (mod MOD) inline long long sum_j(unsigned long long l, unsigned long long r) { return submod(tri(r), tri(l - 1)); } // interval map: key = left boundary; value = {right, lastDay} map<long long, Node> seg; // split at position pos; returns iterator to segment starting at pos, // or seg.end() if pos == n+1 (i.e., after the last position) auto split(long long pos) { if (seg.empty()) return seg.end(); auto it = seg.upper_bound(pos); if (it == seg.begin()) return seg.begin(); // pos <= first L (shouldn't happen for pos>=1) --it; long long L = it->first, R = it->second.r, V = it->second.val; if (pos > R) return seg.end(); // pos is after this segment (e.g., n+1) if (pos == L) return it; // already starts here // split [L,R] into [L,pos-1] and [pos,R] it->second.r = pos - 1; return seg.emplace(pos, Node{R, V}).first; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); long long n; int q; if (!(cin >> n)) return 0; cin >> q; // initially whole [1..n] has lastDay = 0 seg[1] = Node{n, 0}; for (int i = 0; i < q; ++i) { long long d, l, r; cin >> d >> l >> r; long long dmod = d % MOD; auto itl = split(l); auto itr = split(r + 1); long long prevSum = 0; // sum of lastDay * j over [l,r] for (auto it = itl; it != itr; ++it) { long long L = it->first; long long R = it->second.r; long long last = it->second.val % MOD; long long s = sum_j((unsigned long long)L, (unsigned long long)R); prevSum = addmod(prevSum, mulmod(last, s)); } long long totalJ = sum_j((unsigned long long)l, (unsigned long long)r); long long ans = submod(mulmod(dmod, totalJ), prevSum); cout << ans << '\n'; // assign [l,r] := d seg.erase(itl, itr); seg[l] = Node{r, d}; // (optional) light merging with neighbors having the same value d // to keep the map small; not required for correctness. auto itNew = seg.find(l); // merge with previous if (itNew != seg.begin()) { auto itPrev = itNew; --itPrev; if (itPrev->second.r + 1 == itNew->first && itPrev->second.val == itNew->second.val) { itPrev->second.r = itNew->second.r; seg.erase(itNew); itNew = itPrev; } } // merge with next auto itNext = next(itNew); if (itNext != seg.end()) { if (itNew->second.r + 1 == itNext->first && itNext->second.val == itNew->second.val) { itNew->second.r = itNext->second.r; seg.erase(itNext); } } } return 0; }
Идеи ключевые