Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * code generated by JHelper
- * More info: https://github.com/AlexeyDmitriev/JHelper
- * @author
- */
- #include <iostream>
- #include <fstream>
- #include <algorithm>
- #include <array>
- #include <bitset>
- #include <cassert>
- #include <climits>
- #include <cmath>
- #include <complex>
- #include <cstdio>
- #include <cstdlib>
- #include <cstring>
- #include <functional>
- #include <iostream>
- #include <map>
- #include <memory>
- #include <numeric>
- #include <queue>
- #include <random>
- #include <set>
- #include <stack>
- #include <string>
- #include <unordered_map>
- #include <vector>
- #define pb push_back
- #define sz(v) ((int)(v).size())
- #define all(v) (v).begin(),(v).end()
- #define mp make_pair
- using namespace std;
- typedef long long int64;
- typedef vector<int> vi;
- typedef pair<int, int> ii;
- const int BUBEN = 200;
- class TaskK {
- public:
- int n;
- int m;
- vector<vector<int>> children;
- vector<vector<int>> nchildren;
- vector<int> depth;
- vector<int> right;
- vector<int> where;
- int dfsOrderPtr;
- vector<vector<int>> byDepth;
- vector<vector<int>> byDepthFenwick;
- //vector<vector<int>> byDepthModulo;
- //vector<vector<int>> byDepthModuloFenwick;
- int dfs(int root, int d) {
- int us = dfsOrderPtr++;
- depth[us] = d;
- where[root] = us;
- for (int x : children[root]) {
- nchildren[us].push_back(dfs(x, d + 1));
- }
- right[us] = dfsOrderPtr;
- return us;
- }
- void fupd(vector<int>& fenwick, int at, int by) {
- while (at < fenwick.size()) {
- fenwick[at] += by;
- at |= (at + 1);
- }
- }
- int fget(const vector<int>& fenwick, int upto) {
- int res = 0;
- while (upto >= 0) {
- res += fenwick[upto];
- upto = (upto & (upto + 1)) - 1;
- }
- return res;
- }
- void solveOne(istream &in, ostream &out) {
- in >> n >> m;
- children = vector<vector<int>>(n);
- for (int i = 1; i < n; ++i) {
- int p;
- in >> p;
- --p;
- children[p].push_back(i);
- }
- depth = vector<int>(n);
- where = vector<int>(n);
- right = vector<int>(n);
- dfsOrderPtr = 0;
- nchildren = vector<vector<int>>(n);
- dfs(0, 0);
- assert(dfsOrderPtr == n);
- children = nchildren;
- byDepth = vector<vector<int>>(n);
- for (int i = 0; i < n; ++i) {
- byDepth[depth[i]].push_back(i);
- }
- byDepthFenwick = vector<vector<int>>(n);
- for (int i = 0; i < n; ++i) {
- byDepthFenwick[i].resize(byDepth[i].size());
- }
- /*byDepthModulo = vector<vector<vector<int>>>(BUBEN);
- byDepthModuloFenwick = vector<vector<vector<int>>>(BUBEN);
- vector<int> counts;
- for (int x = 1; x < BUBEN; ++x) {
- counts.clear();
- counts.resize(BUBEN, 0);
- for (int i = 0; i < n; ++i) {
- ++counts[depth[i] % x];
- }
- byDepthModulo[x].resize(x);
- byDepthModuloFenwick[x].resize(x);
- for (int i = 0; i < x; ++i) {
- byDepthModulo[x][i].reserve(counts[i]);
- byDepthModuloFenwick[x][i].resize(counts[i]);
- }
- for (int i = 0; i < n; ++i) {
- byDepthModulo[x][depth[i] % x].push_back(i);
- }
- for (int i = 0; i < x; ++i) {
- assert(byDepthModuloFenwick[x][i].size() == byDepthModulo[x][i].size());
- }
- }*/
- vector<int> kinds(m);
- vector<int> as(m);
- vector<int> xs(m);
- vector<int> ys(m);
- vector<int> zs(m);
- vector<int> results(m);
- for (int mi = 0; mi < m; ++mi) {
- int kind;
- in >> kind;
- kinds[mi] = kind;
- if (kind == 1) {
- int a, x, y, z;
- in >> a >> x >> y >> z;
- --a;
- a = where[a];
- as[mi] = a;
- xs[mi] = x;
- ys[mi] = y;
- zs[mi] = z;
- if (x >= BUBEN) {
- for (int d = depth[a] + y; d < n; d += x) {
- int from = lower_bound(all(byDepth[d]), a) - byDepth[d].begin();
- int to = lower_bound(all(byDepth[d]), right[a]) - byDepth[d].begin();
- fupd(byDepthFenwick[d], from, z);
- fupd(byDepthFenwick[d], to, -z);
- }
- }
- } else if (kind == 2) {
- int a;
- in >> a;
- --a;
- a = where[a];
- as[mi] = a;
- int res = 0;
- int d = depth[a];
- int from = lower_bound(all(byDepth[d]), a) - byDepth[d].begin();
- res += fget(byDepthFenwick[d], from);
- results[mi] = res;
- } else {
- assert(false);
- }
- }
- for (int cx = 1; cx < BUBEN; ++cx) {
- byDepth.clear();
- byDepth.resize(cx);
- for (int i = 0; i < n; ++i) {
- byDepth[depth[i] % cx].push_back(i);
- }
- byDepthFenwick.clear();
- byDepthFenwick.resize(cx);
- for (int i = 0; i < cx; ++i) {
- byDepthFenwick[i].resize(byDepth[i].size());
- }
- for (int mi = 0; mi < m; ++mi) {
- int kind = kinds[mi];
- if (kind == 1) {
- int a = as[mi];
- int x = xs[mi];
- int y = ys[mi];
- int z = zs[mi];
- if (x == cx) {
- y = (y + depth[a]) % x;
- int from = lower_bound(all(byDepth[y]), a) - byDepth[y].begin();
- int to = lower_bound(all(byDepth[y]), right[a]) - byDepth[y].begin();
- fupd(byDepthFenwick[y], from, z);
- fupd(byDepthFenwick[y], to, -z);
- }
- } else if (kind == 2) {
- int a = as[mi];
- int x = cx;
- int y = depth[a] % x;
- int from = lower_bound(all(byDepth[y]), a) - byDepth[y].begin();
- results[mi] += fget(byDepthFenwick[y], from);
- } else {
- assert(false);
- }
- }
- }
- for (int mi = 0; mi < m; ++mi) {
- if (kinds[mi] == 2) {
- out << results[mi] << "\n";
- }
- }
- }
- void solve(std::istream &in, std::ostream &out) {
- int nt;
- in >> nt;
- for (int it = 0; it < nt; ++it) {
- solveOne(in, out);
- }
- }
- };
- int main() {
- ios_base::sync_with_stdio(false);
- cin.tie(NULL);
- TaskK solver;
- std::istream& in(std::cin);
- std::ostream& out(std::cout);
- solver.solve(in, out);
- return 0;
- }
Add Comment
Please, Sign In to add comment