W
H
X

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

。。。。

posted @ 2021-06-09 16:18  -敲键盘的猫-  阅读(24)  评论(0编辑  收藏  举报