Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define endl "\n"
- const int MAXN = 1e5 + 10, MAXM = 1e7 + 10;
- int d[4 * MAXN];
- vector <pair<int, int> > rmq;
- vector <int> g[MAXN];
- int founded[MAXN];
- long long a[2 * MAXM];
- bool used[MAXN];
- long long n, m;
- void full() {
- for (int i = 2; i < 4 * MAXN; i++)
- d[i] = d[i / 2] + 1;
- }
- void dfs(int u, int h, long long& i) {
- used[u] = true;
- founded[u] = i;
- rmq.push_back({h, u});
- for (int v : g[u]) {
- if (!used[v]) {
- i++;
- dfs(v, h + 1, i);
- rmq.push_back({h, u});
- i++;
- }
- }
- }
- /*
- void print() {
- cout << " a " << endl;
- for (int i = 0; i < 2 * m; i++) {
- cout << a[i] << " ";
- }
- cout << endl << " rmq " << endl;
- for (unsigned i = 0; i < rmq.size(); i++) {
- cout << rmq[i].first << " ";
- }
- cout << endl;
- for (unsigned i = 0; i < rmq.size(); i++) {
- cout << rmq[i].second << " ";
- }
- cout << endl << " first meat " << endl;
- for (unsigned i = 0; i < n; i++) {
- cout << founded[i] << " ";
- }
- cout << endl << " Now program " << endl;
- }
- */
- signed main() {
- /*
- 14 10
- 0 1 0 0 2 3 6 4 4 5 5 8 3
- 12 9
- 1 1 1
- */
- full();
- cin >> n >> m;
- for (int i = 1; i < n; i++) {
- int v;
- cin >> v;
- g[v].push_back(i);
- g[i].push_back(v);
- }
- cin >> a[0] >> a[1];
- long long x, y, z;
- cin >> x >> y >> z;
- for (int i = 2; i < 2 * m; i++) {
- a[i] = (x * a[i - 2] + y * a[i - 1] + z) % n;
- }
- long long o = 0;
- dfs(0, 0, o);
- // print();
- pair<int, int> Sparse[rmq.size()][30];
- for (int i = 0; i < rmq.size(); i++) {
- Sparse[i][0] = rmq[i];
- }
- for (int k = 1; k < 20; k++) {
- for (int i = 0; i < (int) rmq.size() - (1 << (k - 1)); i++) {
- Sparse[i][k] = min(Sparse[i][k - 1], Sparse[i + (1 << (k - 1))][k - 1]);
- }
- }
- long long last_ans = 0, a1 = a[0], a2 = a[1];
- long long sum = 0;
- for (int i = 0; i < m; i++) {
- a1 = a[2 * i], a2 = a[2 * i + 1];
- a1 = (a1 + last_ans) % n;
- // cout << a1 << " " << a2;
- int L = founded[a1], R = founded[a2];
- if (L > R) {
- swap(L, R);
- }
- // cout << " [] " << L << " " << R << " " << d[R - L];
- pair <int, int> ans;
- if (R == L) {
- ans = Sparse[L][0];
- } else {
- int p = d[R - L];
- ans = min(Sparse[L][p], Sparse[R - (1 << (p))][p]);
- }
- // cout << " LCA " << ans.second << endl;
- sum += ans.second;
- last_ans = ans.second;
- }
- cout << sum;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement