Educational Codeforces Round 6 E. New Year Tree

The meaning of problems

Given a rooted tree, given m operations, so that all operations 1 represents a subtree of a node in this tree infected with a certain color, the query operation 2 represents the number of nodes and their subtree colors.

Thinking

For a rooted tree, we rely dfs sequence can be converted into an ordered sequence, the sequence can be established according to dfs tree line.
For the operating segments of the tree, updates, update interval, pushing lazy mark, the question is how to count the number of colors, which is also related to how we're going to push lazy mark.
If simple modifications, permutations tree [root] = val Thus, our combined time interval, for the leaf node is the father can be combined, as can be determined whether the same two leaves, so that the number of ++, whereas for the father leaves father, there is no way a number of different statistics.
We have further found that only 60 kinds of color, you obviously implied, pressure-like thinking.
So change it updates the traditional segment tree way, we can use bit operations to update each time to take the pressure out of a good state, traversed 1-60, have something to answer 1 plus 1 can be.
ps: a small tips to write so long to find: (wa update on the situation as another tree, pay attention to the line when the tree updated, in general, if the update interval or when the tree + = tree | =, then that is for direct the interval did influence his sub-tree has no effect on him, so there is no pushup, likewise, have pushup time, tree section is updated with the = sign.)

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    #include<climits>
    #include<stack>
    #include<vector>
    #include<queue>
    #include<set>
    #include<map>
    //#include<regex>
    #include<cstdio>
    #define up(i,a,b)  for(int i=a;i<b;i++)
    #define dw(i,a,b)  for(int i=a;i>b;i--)
    #define upd(i,a,b) for(int i=a;i<=b;i++)
    #define dwd(i,a,b) for(int i=a;i>=b;i--)
    //#define local
    typedef long long ll;
    const double esp = 1e-6;
    const double pi = acos(-1.0);
    const int INF = 0x3f3f3f3f;
    const int inf = 1e9;
    using namespace std;
    int read()
    {
        char ch = getchar(); int x = 0, f = 1;
        while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
        while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
        return x * f;
    }
    typedef pair<int, int> pir;
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lrt root<<1
    #define rrt root<<1|1
    int n, m;
    const int N = 4e5 + 10;
    ll lazy[N<<2];
    ll tree[N<<2];
    int st[N], ed[N];
    struct {
        int to, next;
    }edge[2*N];
    int head[N];
    int cnt = 0;
    int a[N];
    void addedge(int u, int v)
    {
        edge[cnt].to = v;
        edge[cnt].next = head[u];
        head[u] = cnt++;
    }
    int num = 0;
    void dfs(int u,int f)
    {
        st[u] = ++num;
        for (int i = head[u]; ~i; i = edge[i].next)
        {
            if (edge[i].to != f)dfs(edge[i].to,u);
        }
        ed[u] = num;
    }
    void pushup(int root)
    {
        ll temp = 0; temp |= tree[lrt]; temp |= tree[rrt];
        tree[root] = temp;
    }
    void pushdown(int root)
    {
        if (lazy[root])
        {
            lazy[lrt] = lazy[root];
            lazy[rrt] = lazy[root];
            tree[lrt] = lazy[root];
            tree[rrt] = lazy[root];
            lazy[root] = 0;
        }
    }
    void build(int l, int r, int root)
    {
        lazy[root] = 0;
        if (l == r)
        {
            tree[root] = 0;
            return;
        }
        int mid = (l + r) >> 1;
        build(lson);
        build(rson);
        pushup(root);
    }
    void update(int l, int r, int root, int lf, int rt,int val)
    {
        if (lf <= l && r <= rt)
        {
            tree[root] = (1ll << val);
            lazy[root] = (1ll << val);
            return;
        }
        pushdown(root);
        int mid = (l + r) >> 1;
        if (lf <= mid)update(lson, lf, rt, val);
        if (rt > mid)update(rson, lf, rt, val);
        pushup(root);
    }
    ll querry(int l, int r, int root, int lf, int rt)
    {
        if (lf <= l && r <= rt)
        {
            return tree[root];
        }
        pushdown(root);
        int mid = (l + r) >> 1;
        ll ans = 0;
        if (lf <= mid)ans |= querry(lson, lf, rt);
        if (rt > mid)ans |= querry(rson, lf, rt);
        return ans;
    }
    int main()
    {
        n = read(); m = read();
        int x, y;
        memset(head, -1, sizeof(head));
        up(i, 0, n)a[i] = read();
        up(i, 0, n - 1)
        {
            x = read(), y = read();
            addedge(x, y); addedge(y, x);
        }
        dfs(1, 0);
        build(1, n, 1);
        up(i, 0, n)update(1, n, 1, st[i + 1], st[i + 1], a[i]);
        int op;
        while (m--)
        {
            op = read();
            if (op == 1)
            {
                x = read(), y = read();
                update(1, n, 1, st[x], ed[x], y);
            }
            else
            {
                x = read();
                ll ans = querry(1, n, 1, st[x], ed[x]);
                int temp = 0;
                upd(i, 1, 61)
                {
                    if ((1ll << i)&ans)temp++;
                }
                printf("%d\n", temp);
            }
        }
        return 0;
    }

Guess you like

Origin www.cnblogs.com/LORDXX/p/11566775.html
Recommended