Cattle off -DongDong number of colors and similar questions

Gangster blog

ps: do not question on the cattle off, make up two related questions later learned. Incidentally record it.

Cattle off -DongDong number of colors

Sol: dfs sequence Mo + team, the tree-point scale dfs first sequence, because the subtree dfs sequence is continuous, the sub-tree can be represented as id [x] to id [x] + size [x ] + 1, then the sequence is on the Mok team (official title since dereference)

  • dfs sequence + Mo team
    #include "bits/stdc++.h"
    using namespace std;
    typedef pair<int, int> PII;
    const int MAXN = 1e5 + 10;
    int c1[MAXN], c2[MAXN], c3[MAXN];
    vector<int> edge[MAXN];
    PII node[MAXN]; 
    int pos, size;
    int ans[MAXN];
    struct Query {
        int l, r;
        int index;
    } q[MAXN];
    void dfs(int u, int f) {
        c2[++pos] = c1[u];
        node[u].first = pos;
        for (int i = 0; i < edge[u].size(); i++) {
            int v = edge[u][i];
            if (v == f) continue;
            dfs(v, u);
        }
        node[u].second = pos;
    }
    bool cmp(Query a, Query b) {
        if ((a.l - 1) / size != (b.l - 1) / size)
            return (a.l - 1) / size < (b.l - 1) / size;
        return a.r < b.r;
    }
    int main() {
        int n, m;
        scanf("%d%d", &n, &m);
        size = sqrt(n);
        for (int i = 1; i <= n; i++)
            scanf("%d", &c1[i]);
        for (int i = 1; i < n; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            edge[u].push_back(v);
            edge[v].push_back(u);
        }
        dfs(1, -1);
        for (int i = 1; i <= m; i++) {
            int x;
            scanf("%d", &x);
            q[i].l = node[x].first;
            q[i].r = node[x].second;
            q[i].index = i;
        }
        sort (q + 1, q + 1 + m, cmp);
        int l = 1, r = 0, k = 0;
        for (int i = 1; i <= m; i++) {
            while (r < q[i].r) if (++c3[c2[++r]] == 1) k++;
            while (l > q[i].l) if (++c3[c2[--l]] == 1) k++;
            while (r > q[i].r) if (--c3[c2[r--]] == 0) k--;
            while (l < q[i].l) if (--c3[c2[l++]] == 0) k--;
            ans[q[i].index] = k;
        }
        for (int i = 1; i <= m; i++) 
            printf("%d\n", ans[i]);
        return 0;
    }
    View Code

     

ps: Due to two other solution on my dish, official explanations did not make it, but go online to read the other blogger's blog can be found with Fenwick tree instead of Mo team function more efficiently. Array array is n * log (n), Mo team for n * sqrt (n)

HDU-3333-Turing Tree

sol: offline processing, priority of the right front section, constantly updated index position for each color, so that the weight sum statistically Fenwick tree;

  • Fenwick tree
    #include "bits/stdc++.h"
    using namespace std;
    typedef long long LL;
    const int MAXN = 1e5 + 10;
    struct Query {
        int l, r;
        int index;
    } q[MAXN];
    int a[MAXN], pre[MAXN];
    LL c[MAXN], ans[MAXN];
    map<int, int> mp;
    bool cmp(Query a, Query b) {
        return a.r < b.r;
    }
    int lowbit(int i) {
        return i & (-i);
    }
    void add(int i, int k) {
        while (i < MAXN) {
            c[i] += k;
            i += lowbit(i);
        }
    }
    LL sum(int i) {
        LL res = 0;
        while (i > 0) {
            res += c[i];
            i -= lowbit(i);
        }
        return res;
    }
    int main() {
        int t, n, m;
        scanf("%d", &t);
        while (t--) {
            memset(c, 0, sizeof(c));
            mp.clear();
            scanf("%d", &n);
            for (int i = 1; i <= n; i++)
                scanf("%d", &a[i]);
            scanf("%d", &m);
            for (int i = 1; i <= m; i++) {
                scanf("%d%d", &q[i].l, &q[i].r);
                q[i].index = i;
            }
            sort(q + 1, q + 1 + m, cmp);
            int r = 0;
            for (int i = 1; i <= m; i++) {
                while (r < q[i].r) {
                    ++r;
                    add(r, a[r]);
                    if (mp.count(a[r])) add(mp[a[r]], -a[r]);
                    mp[a[r]] = r;
                }
                ans[q[i].index] = sum(q[i].r) - sum(q[i].l - 1);
            }
            for (int i = 1; i <= m; i++)
                printf("%lld\n", ans[i]);
        }
        return 0;
    }
    View Code

     

ps: according to the degree of difficulty in this question should be ranked above the previous question, is entirely a question of the emasculated version. Mo on a problem with the team to write this question on the method used to train the tree array, but this problem had not be able to team with Mo, this code is an array of arrays are run 468ms, Mo team may be more limit, not tried.

CF-703D-Mishka and Interesting sum

sol: the interval so the number of XOR up according to the same figures XOR get to the principle of zero is that all occurrences odd XOR value of the number, then contact the two questions above, the number as long as no recurring interval are different or again in the number of exclusive-oR and what is the result of our all within the range. Because the exclusive Canadian or subtraction have some of the same properties can also be used Fenwick tree to solve.

  • Fenwick tree Bitwise +
    #include "bits/stdc++.h"
    using namespace std;
    const int MAXN = 1e6 + 10;
    int a[MAXN], b[MAXN], c[MAXN];
    map<int, int> mp;
    int ans[MAXN];
    struct Query {
        int l, r;
        int index;
    } q[MAXN];
    bool cmp(Query a, Query b) {
        return a.r < b.r;
    }
    int lowbit(int i) {
        return i & (-i);
    }
    void add(int i, int k) {
        while (i < MAXN) {
            c[i] ^= k;
            i += lowbit(i);
        }
    }
    int sum(int i) {
        int _xor = 0;
        while (i > 0) {
            _xor ^= c[i];
            i -= lowbit(i);
        }
        return _xor;
    }
    int main() {
        int n, m;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            b[i] = a[i] ^ b[i - 1];
        }
        scanf("%d", &m);
        for (int i = 1; i <= m; i++) {
            scanf("%d%d", &q[i].l, &q[i].r);
            q[i].index = i;
        }
        sort(q + 1, q + 1 + m, cmp);
        int r = 0;
        for (int i = 1; i <= m; i++) {
            while (r < q[i].r) {
                r++;
                add(r, a[r]);
                if (mp.count(a[r]))
                    add(mp[a[r]], a[r]);
                mp[a[r]] = r;
            }
            ans[q[i].index] = (sum(q[i].r) ^ sum(q[i].l - 1)) ^ (b[q[i].r] ^ b[q[i].l - 1]);
        }
        for (int i = 1; i <= m; i++)
            printf("%d\n", ans[i]);
        return 0;
    }
    View Code

     

ps: this problem I tried Mo team, timed out, stuck in the 14 sets of data, Mo lead a team of data 1e5, this problem n maximum of 1e6. Mo better team write, but still Fenwick tree faster.

Mo + team dfs sequence, the first sequence dfs tree-point scale, because the subtree dfs sequence is continuous, the sub-tree can be represented as id [x] to id [x] + size [X] + 1'd I D [ X ] to I D [ X ] + S I Z E [ X ] + . 1 , and then the sequence is the team Mo

Guess you like

Origin www.cnblogs.com/Angel-Demon/p/11448830.html