Codeforces Round #625 (Div. 1)
Codeforces Round #625 (Div. 1)
A
略
B
略
C
略
D
只关注 \(0\) 在哪些位置,发现:所有 \(0\) 的下标奇偶性不变,一个 \(0\) 不能跨过另一个 \(0\),在此基础上可以随意的移动。那么把两个串中的 \(0\) 所在位置的奇偶性拿出来按顺序排列,构成一个 \(01\) 串,如果两个串相同就可行,\(hash\) 处理一下。
int n, q, m, c[N]; char a[N];
ll s[N][2], p[N];
#define qwq(x) ((x) % mod + mod) % mod
#define mod(x) ((x) % mod)
ll ask (int l, int r) {
int t = l & 1; l = c[l - 1] + 1, r = c[r];
return qwq (s[r][t] - s[l - 1][t] * p[r - l + 1]);
}
signed main() {
scanf ("%d %s %d", &n, a + 1, &q); p[0] = 1;
for (int i = 1; i <= n; ++i) p[i] = p[i - 1] * o % mod;
for (int i = 1; i <= n; ++i) {
if (a[i] == '0') {
++m;
s[m][0] = mod (s[m - 1][0] * o + 1 + (i & 1));
s[m][1] = mod (s[m - 1][1] * o + 2 - (i & 1));
}
c[i] = m;
}
for (int i = 1, l, x, y; i <= q; ++i) {
read (x), read (y), read (l);
puts (ask (x, x + l - 1) == ask (y, y + l - 1) ? "Yes" : "No");
}
return 0;
}
E
题目描述疯狂暗示我们要建虚树,那就先建出来吧。然后就成了多源最短路问题,但为了保证顺序需要用 \(dijkstra\)。
F
int n, cnt, h[N], nxt[M], to[M];
void add (int u, int v) {
to[++cnt] = v, nxt[cnt] = h[u], h[u] = cnt;
}
int tot, d[N], tp[N], dfn[N], fa[N], sz[N], son[N];
void dfs (int u) {
sz[u] = 1, d[u] = d[fa[u]] + 1;
for (int i = h[u], v; i; i = nxt[i]) {
if ((v = to[i]) == fa[u]) continue;
fa[v] = u, dfs (v), sz[u] += sz[v];
if (sz[v] > sz[son[u]]) son[u] = v;
}
}
void dfs (int u, int topp) {
tp[u] = topp, dfn[u] = ++tot; if (son[u]) dfs (son[u], topp);
for (int i = h[u], v; i; i = nxt[i]) if (!dfn[v = to[i]]) dfs (v, v);
}
void prework () { dfs (1), dfs (1, 1); }
int get (int x, int y) {
while (tp[x] != tp[y])
d[tp[x]] < d[tp[y]] ? y = fa[tp[y]] : x = fa[tp[x]];
return d[x] > d[y] ? y : x;
}
vector<int> a, b, p, q, g[N]; int w[N], t, s[N], in[N];
#define pb push_back
bool cmp (int x, int y) { return dfn[x] < dfn[y]; }
void link (int x, int y) { g[x].pb (y), g[y].pb (x); }
void build () {
sort (p.begin(), p.end (), cmp);
p.erase (unique (p.begin(), p.end()), p.end ()); q = p;
for (int x : p) {
int lca = get (x, s[t]);
if (lca != s[t]) {
while (t && d[s[t - 1]] >= d[lca]) link (s[t - 1], s[t]), --t;
if (s[t] != lca) link (lca, s[t]), s[t] = lca, q.pb (lca);
}
s[++t] = x;
}
while (t && --t) link (s[t + 1], s[t]); p = q;
}
struct node {
int d, id, x, r;
node () {}
node (int d, int id, int x) : d (d), id (id), x (x) {
r = (d + w[x] - 1) / w[x];
}
bool operator < (const node p) const {
return r == p.r ? id > p.id : r > p.r;
}
} o[N];
priority_queue<pair<node, int> > qq;
void calc () {
for (int x : p) o[x].r = o[x].id = n + 1, in[x] = 0;
for (int i = 0; i < a.size(); ++i)
o[a[i]] = node (0, i + 1, a[i]), qq.push ({o[a[i]], a[i]});
while (!qq.empty()) {
int u = qq.top().second; qq.pop();
if (in[u]) continue; in[u] = 1;
for (int v : g[u]) {
node t = node (o[u].d + abs (d[u] - d[v]), o[u].id, o[u].x);
if (!(t < o[v])) o[v] = t, qq.push ({o[v], v});
}
}
}
signed main() {
read (n);
for (int i = 1, u, v; i < n; ++i)
read (u), read (v), add (u, v), add (v, u);
int q; read (q); prework ();
for (int T = 1, ca, cb; T <= q; ++T) {
read (ca), read (cb);
a.clear (), b.clear (), p.clear ();
for (int i = 1, x; i <= ca; ++i)
read (x), read (w[x]), a.pb (x), p.pb (x);
for (int i = 1, x; i <= cb; ++i)
read (x), b.pb (x), p.pb (x);
build (), calc ();
for (int x : b) printf ("%d ", o[x].id); puts ("");
for (int x : p) g[x].clear ();
}
return 0;
}
F
。。。。