zoukankan      html  css  js  c++  java
  • New Year Tree 【DFS序+线段树区间查询修改+二进制保存状态】

    题目链接【http://codeforces.com/problemset/problem/620/E】

    题意:给出n个数,每个数有一个初始的颜色。由这n个数组成一颗树。有两种操作1、将以节点u为根的子树的颜色染成k色。2、输出以节点u为根的子树的颜色总数。颜色有60种。

    题解:1、用DFS重新对这棵树编号in[u],out[u]表示以节点u为根的子树的区间左右端点。2、用线段树维护更新与查询。3、颜色保存:se每一个二进制位表示一种颜色。0表示没有这种颜色,反之有。

    因为有60种颜色,要用LL保存颜色。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int maxn = 1e6+5;
    vector<int> v[maxn];
    int in[maxn],out[maxn];
    LL c[maxn];
    int n,m;
    int id;
    void DFS_ORDER(int u)
    {
        in[u] = ++id;
        for(int i = 0;i < v[u].size();i++)
        {
            int w = v[u][i];
            if(!in[w])    DFS_ORDER(w);
        }
        out[u] = id;
    }
    LL E[maxn*4],T[maxn*4];//值数组,标记数组
    void update(int id,int l,int r,int In,int Out,LL val)
    {
        if(r < In || l > Out)//不重合
            return ;
        if(l >= In && Out >= r)//包含
        {
            E[id] = val;
            T[id] = val;
            return ;
        }
        if(T[id])//相交
        {
            int mid = (l+r)>>1;
            T[id << 1] = T[id];
            E[id << 1] = T[id];
            T[id << 1 | 1] = T[id];
            E[id << 1 | 1] = T[id];
            T[id] = 0;//取消标记
        }
        int mid = (l+r) >>1;
        update(id<<1,l,mid,In,Out,val);
        update(id<<1|1,mid+1,r,In,Out,val);
        E[id] = E[id<<1]|E[id<<1|1];
    }
    LL query(int id,int l,int r,int In,int Out)
    {
        if(r < In || l > Out)//不重合
            return 0;
        if(l >= In && Out >= r)//包含
            return E[id];
        if(T[id])//相交
        {
            int mid = (l+r)>>1;
            T[id << 1] = T[id];
            E[id << 1] = T[id];
            T[id << 1 | 1] = T[id];
            E[id << 1 | 1] = T[id];
            T[id] = 0;//取消标记
        }
        int mid = (l+r) >>1;
        LL ans1 = query(id<<1,l,mid,In,Out);
        LL ans2 = query(id<<1|1,mid+1,r,In,Out);
        return ans1|ans2;
    }
    int main ()
    {
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;i++)
            scanf("%lld", &c[i]);
        for(int i = 1;i <= n-1;i++)
        {
            int u,w;
            scanf("%d%d",&u,&w);
            v[u].push_back( w );
            v[w].push_back( u );
        }
        DFS_ORDER(1);
        for(int i = 1;i <= n;i++)
        {
            LL x = LL(1)<<(c[i]-1);
            update(1,1,n,in[i],in[i],x);
        }
        int ty,u;LL val;
        for(int i = 1;i <= m;i++)
        {
            scanf("%d",&ty);
            if(ty == 1)
            {
                scanf("%d%lld",&u,&val);
                LL x = LL(1)<<(val-1);
                update(1,1,n,in[u],out[u],x);
            }
            else
            {
                scanf("%d",&u);
                LL t = query(1,1,n,in[u],out[u]);
                int ans=0;
                while(t){if(t&1)ans++;t>>=1;}
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
    想的太多,做的太少。
  • 相关阅读:
    HDU 1058 Humble Numbers
    HDU 1160 FatMouse's Speed
    HDU 1087 Super Jumping! Jumping! Jumping!
    HDU 1003 Max Sum
    HDU 1297 Children’s Queue
    UVA1584环状序列 Circular Sequence
    UVA442 矩阵链乘 Matrix Chain Multiplication
    DjangoModels修改后出现You are trying to add a non-nullable field 'download' to book without a default; we can't do that (the database needs something to populate existing rows). Please select a fix:
    opencv做的简单播放器
    c++文件流输入输出
  • 原文地址:https://www.cnblogs.com/pealicx/p/6236111.html
Copyright © 2011-2022 走看看