void InitCost() { MinCost = new MinSegTree[N]; MinCost[0] = new MinSegTree(1); MinCost[0].Set(0, 0); UsedAtmost = new int[N]; for (int i = 1; i < N; i++) { int x = MinUsed[i], cost = N - x + x * (x + 1) / 2; int atmost = MinUsed[i]; for (int bit = 1 << 14; bit > 0; bit >>= 1) { if ((x = atmost + bit) < N && x * (x + 1) / 2 <= cost) { atmost += bit; } } UsedAtmost[i] = atmost; MinCost[i] = new MinSegTree(atmost - MinUsed[i] + 1); } }
public void Solve() { int N = Reader.Int(); var table = new int[1][].Concat(Reader.IntTable(N - 1)).ToArray(); var seg = new MinSegTree(N, -1); seg.Set(0, 0); int grundy = 0; for (int i = 1; i < N; i++) { int L = i - table[i][0], num = table[i][1]; int g = BinarySearchMax(0, N - 1, x => seg.Min(0, x) >= L); seg.Set(g, i); if (num % 2 == 1) { grundy ^= g; } } Console.WriteLine(grundy == 0 ? "Second" : "First"); }