Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <string>
- #include <cstring>
- #include <algorithm>
- #include <fstream>
- #include <iomanip>
- #include <iterator>
- #include <sstream>
- #include <set>
- #include <map>
- #include <unordered_map>
- #include <unordered_set>
- #include <list>
- #include <ctime>
- #include <queue>
- #include <cmath>
- #include <stack>
- #include <functional>
- #include <memory>
- #include <tuple>
- #include <utility>
- using namespace std;
- #define __int64 long long
- const double pi = atan2(0.0, -1.0);
- struct dat
- {
- __int64 el;
- //----- Изменения --------
- __int64 change_add = 0; //Прибавка
- bool dead_end = false; //Проверка на лист
- friend ostream& operator<<(ostream& is, const dat& l);
- };
- ostream& operator<<(ostream& is, const dat& l)
- {
- is << l.el << " ";
- return is;
- }
- struct DO
- {
- private:
- vector<dat> mas; //Само дерево
- vector<__int64> v; //Исходный
- int l, r, n, x;
- function<dat(dat, dat)> fun;//Операция
- public:
- void create(vector<__int64>& _v, function<dat(dat, dat)> _fun)
- {
- v = _v;
- fun = _fun;
- n = v.size()-1;
- mas.resize(4 * n+8);
- create_rec(1, 0, n);
- }
- void update_add(int _l, int _r, int _x)
- {
- l = _l; r = _r; x = _x;
- get(l, r);
- update_add_rec(1, 0, n);
- }
- dat get(int _l, int _r)
- {
- l = _l; r = _r;
- return get_rec(1, 0, n);
- }
- private:
- void create_rec(int ii, int l, int r)
- {
- if (l == r)
- {
- mas[ii].el = v[l];
- mas[ii].dead_end = true;
- }
- else
- {
- int m = (r - l) / 2 + l;
- create_rec(2 * ii, l, m);
- create_rec(2 * ii + 1, m + 1, r);
- mas[ii].el = fun(mas[2 * ii], mas[2 * ii + 1]).el;
- }
- }
- void update_add_rec(int ii, int ll, int rr)
- {
- if ((ll > r) || (rr < l)) return;
- if ((l <= ll) && (rr <= r))
- {
- mas[ii].el += x * (rr - ll + 1);//Прибавить элемент
- mas[ii].change_add+= x;
- return;
- }
- int tm = (rr - ll) / 2 + ll;
- update_add_rec(ii * 2, ll, tm);
- update_add_rec(ii * 2 + 1, tm + 1, rr);
- mas[ii].el = fun(mas[ii * 2], mas[ii * 2 + 1]).el;
- }
- dat get_rec(int ii, int ll, int rr)
- {
- if ((l<=ll) && (rr<=r))
- {
- return mas[ii];
- }
- int tm = (rr - ll) / 2 + ll;
- dat buf;
- //Проталкиваем изменения
- if (mas[ii].change_add)
- {
- if (!mas[ii].dead_end)
- {
- mas[ii * 2].el += mas[ii].change_add * (tm - ll + 1);
- mas[ii * 2 + 1].el += mas[ii].change_add * (rr - tm);
- mas[ii * 2].change_add += mas[ii].change_add;
- mas[ii * 2 + 1].change_add += mas[ii].change_add;
- }
- mas[ii].change_add = 0;
- }
- //---------
- if (tm >= l) buf = get_rec(ii * 2, ll, tm);
- else return get_rec(ii * 2+1, tm+1, rr);
- if (tm < r) return fun(buf, get_rec(ii * 2 + 1, tm + 1, rr));
- else return buf;
- }
- };
- class Global // For zeroing fields in unit test
- {
- public:
- DO d;
- void solve()
- {
- int n, l ,r, x; cin >> n;
- vector<__int64> v(n);
- for (auto& it : v) cin >> it;
- d.create
- (v,
- [](dat l, dat r)
- {
- dat re;
- re.el = l.el + r.el;
- return re;
- }
- );
- cin >> n;
- char ch;
- for (; n--;)
- {
- cin >> ch;
- switch (ch)
- {
- case 'g':
- cin >> l;
- cout<<d.get(l-1, l-1);
- break;
- case 'a':
- cin >> l >> r >> x;
- d.update_add(l - 1, r - 1, x);
- default:
- break;
- }
- }
- } //Конец
- void head()
- {
- int t = 1;
- for (; t--;)
- {
- solve();
- }
- }
- };
- int main()
- {
- // srand(time(0));
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- #ifdef RED
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- int amount_TEST = 1;
- cin >> amount_TEST;
- for (int amount_test = 1; amount_test <= amount_TEST; ++amount_test)
- {
- #endif
- vector<Global> global;
- global.clear();
- global.resize(1);
- global[0].head();
- #ifdef RED
- cout << "\nКонец " << amount_test << " Теста\n";
- }
- #endif
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement