int n, m; int val[maxn]; int cnt[maxn]; int v[maxn];
voidsolve() { sa(n), sa(m); repp(i, 1, n) { sa(val[i]); } repp(i, 1, m) { int le, ri, x; sa(le), sa(ri), sa(x);
int minn = 1e5, maxx = 0; repp(k, le, ri) { cnt[val[k]]++; maxx = max(maxx, val[k]); minn = min(minn, val[k]); } int st = minn; repp(i, le, ri) { while (cnt[st] == 0)st++; cnt[st]--; v[i] = st; } if (v[x] == val[x]) { puts("Yes"); } else { puts("No"); } } }
C.Vladik and Memorable Trip
Given $n$ numbers ($n < 5000$), choosing a value requires choosing the entire interval that contains that value. Find the maximum XOR sum over all chosen intervals.
int sum = 0; repp(k, le, ri) { if (vis[val[k]])continue; sum ^= val[k]; vis[val[k]] = 1; } dp[ri] = max(dp[ri], dp[le - 1] + sum); dp[i] = max(dp[i], dp[i - 1]); repp(k, le, ri) { vis[val[k]] = 0; } } ll ans = 0; repp(i, 1, n) { ans = max(ans, dp[i]); } printf("%lld\n", ans); }
D. Vladik and Favorite Game
An interactive problem. Starting at $(1,1)$, navigate a robot to a given target. The “Up” and “Down” controls may be reversed, as may “Left” and “Right”. The board contains traps, and landing on one loses the game.
Because $(1,1)$ is the upper-left corner, one control mapping can be determined immediately. While moving along the boundary, the other can also be determined. Then a straightforward BFS/DFS works.
repp(k, 1, 4) { int nx = x + dx4[k]; int ny = y + dy4[k]; if ((val[nx][ny] == '.')&& step[nx][ny] == -1) { step[nx][ny] = step[x][y] - 1; que.push(mp(nx, ny)); } } } }
voiddfs(int x, int y) { if (val[x][y] == 'F')return; int dir = 1; int px, py; repp(k, 1, 4) { int nx = x + dx4[k]; int ny = y + dy4[k]; if (step[nx][ny] == step[x][y] + 1) { px = nx; py = ny; dir = k; break; } } printf("%c\n", v[dir]); fflush(stdout);
int newx, newy; sa(newx), sa(newy); if (newx == px && newy == py) { dfs(newx, newy); } else { if (dir == 1 || dir == 3) { swap(v[1], v[3]); } else { swap(v[2], v[4]); } dfs(x, y); } }
Given an $n \times m$ grid ($n < 10$, $m < 10^5$) of numbers and $q$ queries, each query covers a vertical slice of the grid and asks for the number of connected regions of equal numbers.
I could not solve this one at the time.
The solution is a segment tree containing disjoint-set structures. Since $n < 10$, each segment can record the component memberships of values on both boundaries; when merging, unite equal colors on the right boundary of the left segment and the left boundary of the right segment.
for (int i = 1; i <= n; i++) { if (val[i][ri] == val[i][other.le]) { res.ans -= dsu.uni(i + n, i + 2 * n); } } for (int i = 0; i <= 40; i++) { tmp[i].clear(); } for (int i = 1; i <= n; i++) { tmp[dsu.find(i)].push_back(i); tmp[dsu.find(i + 3 * n)].push_back(i + n); } for (int i = 0; i <= 40; i++) { for (int k = 0; k < tmp[i].size(); k++) { res.col[tmp[i][k]] = tmp[i][0]; } } return res; } }no[4 * maxn];
voidbuild(int root, int le, int ri) { if (le == ri) { no[root].le = no[root].ri = le; no[root].init(); return; } int mid = (ri + le) / 2; build(root << 1, le, mid); build(root << 1 | 1, mid + 1, ri); no[root] = no[root << 1] + no[root << 1 | 1]; }
node query(int root, int le, int ri) { if (no[root].le == le&&no[root].ri == ri) { return no[root]; } int mid = (no[root].le + no[root].ri) / 2; if (ri <= mid)returnquery(root << 1, le, ri); if (le > mid)returnquery(root << 1 | 1, le, ri); returnquery(root << 1, le, mid) + query(root << 1 | 1, mid + 1, ri); }
voidsolve() { sa(n), sa(m), sa(q); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { scanf("%d", &val[i][j]); } } build(1, 1, m); repp(i, 1, q) { int x, y; sa(x), sa(y); node res = query(1, x, y); printf("%d\n", res.ans); } }