Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma comment(linker,"/STACK:300000000")
- #include <stdio.h>
- #include <iostream>
- #include <math.h>
- #include <vector>
- #include <map>
- #include <set>
- #include <algorithm>
- #include <queue>
- #include <string>
- #include <string.h>
- #include <ctype.h>
- #include <iomanip>
- #include <iterator>
- #include <unordered_map>
- #include <unordered_set>
- #include <stdlib.h>
- using namespace std;
- typedef long long ll;
- typedef unsigned long long ull;
- typedef long double ld;
- typedef pair<int, int> pii;
- typedef vector<int> vi;
- typedef vector<vi> vvi;
- typedef pair<ll, ll> pll;
- typedef pair<ull, ull> pull;
- #define pb push_back
- #define mp make_pair
- #define eps 1e-9
- #define PI 3.14159265358979323846
- #define ACCEPTED return 0;
- #define name ""
- const int maxlen = (int)(2e5) + 10;
- const int base = (int)(1e9);
- const ll mod = 1000 * 1000 * 1000 + 7;
- const ll bigmod = 99194853094755497ll;
- const ll infinity = (ll) 1e18;
- ll C[(int)1e6 + 10];
- ll h[maxlen];
- pii T[maxlen];
- ll timer = 0;
- vector<vector<ll>> G;
- ll N;
- void initN(ll n)
- {
- N = 1;
- while (N < n)
- N <<= 1;
- }
- pll t[1 << 20];
- pll GetMax(ll v, ll tl, ll tr, ll l, ll r)
- {
- if (l > r)
- return mp(-1ll, -1ll);
- if (tl == l && tr == r)
- return t[v];
- ll tm = (tl + tr) / 2;
- pll l1 = GetMax(2 * v, tl, tm, l, min(r, tm));
- pll l2 = GetMax(2 * v + 1, tm + 1, tr, max(l, tm + 1), r);
- return max(l1, l2);
- }
- void update(int v, ll value)
- {
- v = N + v;
- t[v] = mp(value, 1ll*v);
- while (v > 1)
- {
- v >>= 1;
- t[v] = max(t[2 * v], t[2 * v + 1]);
- }
- }
- void dfsHeight(ll v = 0, ll height = 0)
- {
- T[v].first = timer++;
- update(T[v].first, v);
- h[v] = height;
- for (int i = 0; i < G[v].size(); ++i)
- dfsHeight(G[v][i], height + 1);
- T[v].second = timer - 1;
- }
- bool comp(int a, int b)
- {
- return h[a] > h[b];
- }
- int main()
- {
- #ifdef _DEBUG
- freopen("input.txt", "rt", stdin);
- freopen("output.txt", "wt", stdout);
- #endif
- int turns;
- scanf("%d", &turns);
- for (int turn = 1; turn <= turns; ++turn)
- {
- printf("Case #%d: ", turn);
- ll n, m, A, B;
- scanf("%lld %lld %lld %lld", &n, &m, &A, &B);
- G.clear();
- initN(n);
- G.resize(n);
- memset(C, 0, sizeof(C));
- memset(h, 0, sizeof(h));
- memset(T, 0, sizeof(T));
- memset(t, 0, sizeof(t));
- timer = 0;
- for (ll i = 0; i < m; ++i)
- C[i] = (A * i + B) % n;
- ll ans = 0;
- for (ll i = 1; i < n; ++i)
- {
- int p;
- scanf("%d", &p);
- G[p].push_back(i);
- }
- dfsHeight();
- sort(C, C + m, comp);
- for (int i = 0; i < m; ++i)
- {
- ll p = C[i];
- pll mx = GetMax(1, 0, N - 1, T[p].first, T[p].second);
- if (mx.first != 0ll)
- {
- ans += mx.first;
- update(mx.second - N, 0);
- }
- }
- printf("%lld\n", ans);
- }
- ACCEPTED
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement