[JZOJ6273] [Group A] NOIP improve owe (Money)

Subject to the effect

A rooted tree even dynamic edge, right on the edge of the smallest query chain, which calls for a son to his father, otherwise the output \ (0 \) .
By force, \ (n-\ Leq. 5 ^ 10 \) , the operand \ (m \ Leq. 6 10 ^ \) , there will be multiple edges.

analysis

One approach is even edge \ ((a, b) \ ) when violence modify \ (a \) multiplier array sub-tree of all points, then calculated by multiplying array of answers when asked.

Obviously, the point of each modification related violence is \ (O (n) \) level, the complexity of the modification is \ (O (the n-^ 2logn) \) .

If heuristic combined force to a smaller size from larger communication block connected to the communication block size, the number of times each time point is modified violence \ (O (logn) \) times, each time modifications are \ (O (logn) \) complexity, the complexity of the modifications to reduced \ (O (nlog ^ 2n) \) .

Because you are forced to change his father direction of the tree, when asked (\ (u, v)) \ time, \ (U \) to (lca \) \ all sides of the path of the original direction and father orientation of the tree is consistent (Note : father direction refers to the direction from the son to the father), \ (v \) to \ (lca \) of all edges on the path to the original direction and father direction of the tree opposite, so as to the original tree from \ (u \) to \ (v \) . Then more than doubled to maintain two arrays, respectively, if there is original direction and father direction of the same side, if there is original direction with his father direction opposite edge, then pay attention to two points in this case is not connected, to get this problem .

Time complexity \ (O (nlog 2N + mlogn ^) \) , pay attention to the constant.

Code

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 100007;

inline int read()
{
    int x = 0, f = 0;
    char c = getchar();
    for (; c < '0' || c > '9'; c = getchar()) if (c == '-') f = 1;
    for (; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ '0');
    return f ? -x : x;
}
inline int min(int a, int b)
{
    if (a < b) return a;
    return b;
}

int n, m, fa[N], size[N];
int opt, a, b, c, lastans, flag, ta, tb;
int tot, h, t, st[N], to[N << 1], nx[N << 1], dir[N << 1], val[N << 1], q[N];
void add(int u, int v, int w, int c) { to[++tot] = v, nx[tot] = st[u], dir[tot] = w, val[tot] = c, st[u] = tot; }
int anc[N][17], mi[N][17], tag[2][N][17], dep[N];

inline int getfa(int x) { return fa[x] == x ? x : getfa(fa[x]); }

int getans(int u, int v)
{
    int f = 0, ans = 0x3f3f3f3f;
    if (dep[u] < dep[v]) swap(u, v), f ^= 1;
    for (int i = 16; i >= 0; --i) if (dep[anc[u][i]] >= dep[v])
    {
        if (tag[f][u][i]) return 0;
        ans = min(ans, mi[u][i]), u = anc[u][i];
    }
    if (u == v) return ans;
    for (int i = 16; i >= 0; --i) if (anc[u][i] != anc[v][i])
    {
        if (tag[f][u][i] || tag[!f][v][i]) return 0;
        ans = min(ans, min(mi[u][i], mi[v][i])), u = anc[u][i], v = anc[v][i];
    }
    if (!anc[u][0] && !anc[v][0]) return 0;
    if (tag[f][u][0] || tag[!f][v][0]) return 0;
    ans = min(ans, min(mi[u][0], mi[v][0]));
    return ans;
}

int main()
{
    //freopen("money.in", "r", stdin);
    //freopen("money.out", "w", stdout);
    
    n = read(), m = read();
    for (int i = 1; i <= n; ++i) fa[i] = i, size[i] = 1, dep[i] = 1;
    for (int i = 1; i <= m; ++i)
    {
        opt = read();
        if (opt)
        {
            a = read(), b = read(), a = (a + lastans) % n + 1, b = (b + lastans) % n + 1;
            printf("%d\n", lastans = getans(a, b));
        }
        else
        {
            a = read(), b = read(), c = read(), a = (a + lastans) % n + 1, b = (b + lastans) % n + 1, c = (c + lastans) % n + 1, flag = 0, ta = a, tb = b;
            add(b, a, 0, c), add(a, b, 1, c);
            ta = getfa(a), tb = getfa(b);
            if (size[ta] > size[tb]) swap(a, b), swap(ta, tb), flag ^= 1;
            fa[ta] = tb, size[tb] += size[ta], anc[a][0] = b, mi[a][0] = c, tag[0][a][0] = flag, tag[1][a][0] = !flag, dep[a] = dep[b] + 1;
            h = 1, q[t = 1] = a;
            while (h <= t)
            {
                int u = q[h]; ++h;
                for (int i = 1; i <= 16; ++i)
                {
                    anc[u][i] = anc[anc[u][i - 1]][i - 1];
                    mi[u][i] = min(mi[u][i - 1], mi[anc[u][i - 1]][i - 1]);
                    tag[0][u][i] = (tag[0][u][i - 1] | tag[0][anc[u][i - 1]][i - 1]);
                    tag[1][u][i] = (tag[1][u][i - 1] | tag[1][anc[u][i - 1]][i - 1]);
                }
                for (int i = st[u]; i; i = nx[i])
                    if (to[i] != anc[u][0])
                        anc[to[i]][0] = u, mi[to[i]][0] = val[i], tag[0][to[i]][0] = dir[i], tag[1][to[i]][0] = !dir[i], dep[to[i]] = dep[u] + 1, q[++t] = to[i];
            }
        }
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/zjlcnblogs/p/11300120.html