zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 6 E dfs序+线段树

    题意:给出一颗有根树的构造和一开始每个点的颜色 有两种操作 1 : 给定点的子树群体涂色 2 : 求给定点的子树中有多少种颜色

    比较容易想到dfs序+线段树去做

    dfs序是很久以前看的bilibili上电子科技大学发的视频学习的 将一颗树通过dfs编号的方式 使每个点的子树的编号连在一起作为相连的区间 就可以配合线段树搞子树

    因为以前好像听说过 线段树可以解决一种区间修改和查询区间中不同的xx个数...所以一下子就想到了...

    但是我不会写线段树..只会最简单的单点修改区间查询...不会用延迟标记...所以拿出书现学了一发..

    问学长怎么记录不同的颜色个数 学长就机智的告诉了我用longlong来搞..

    虽然知道了思路..还是写了一天多..

    dfs序 做出每个点的编号 并且记录每个点的子树的编号的左右区间 

    初始进行crea的时候 进行赋值并且pushup

    利用longlong的64位来存有哪种颜色 利用或来做转移

    1L<<50 什么的 好像左移过了多少就崩了..要在外边定义L的变量..哭..

    写线段树好累...(脸上挂满泪痕)...不过桃桃的小粉红敲起来好舒服...

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<map>
    #include<math.h>
    #include<iostream>
    #include<queue>
    #include<string>
    using namespace std;
    #define L long long
    int n , m ;
    struct node{
        int l,r;
        L ma;
    };
    int a[400050];
    node tree[400050*8];
    vector<int >q[400050];
    int id[400050];
    L mark[400050*8];
    int cnt ;
    struct no{
        int l,r;
    };
    no zg[400050];
    int fx[400050];
    void dfs(int u){
        id[u] = ++cnt;
        fx[cnt] = u;
        zg[u].l = cnt;
        for(int i=0;i<q[u].size();i++){
            int v = q[u][i];
            if(id[v] == -1){
               dfs(v);
            }
        }
        zg[u].r = cnt;
    }
    void pushup(int root){
        tree[root].ma = tree[root*2].ma | tree[root*2+1].ma;
    }
    void pushdown(int root){
        if(mark[root] != -1){
            mark[root*2] = mark[root*2+1] = mark[root];
            tree[root].ma = mark[root];
            tree[root*2].ma = tree[root*2+1].ma = mark[root];
            mark[root] = -1;
        }
    }
    void crea(int root ,int l,int r){
        tree[root].l = l;
        tree[root].r = r;
        if(l == r){
            L res = 1;
            res <<= a[fx[l]];
            tree[root].ma = (res);
            return ;
        }
        int m = (l + r) >> 1;
        crea(root*2,l,m);
        crea(root*2+1,m+1,r);
        pushup(root);
    }
    void upda(int root , int l , int r ,int c){
        if(tree[root].r < l || tree[root].l > r){
            return ;
        }
        if(tree[root].r <= r && tree[root].l >= l){
            L res = 1;
            res <<= c;
            mark[root] = (res);
            pushdown(root);
            return ;
        }
        pushdown(root);
        upda(root*2,l,r,c);
        upda(root*2+1,l,r,c);
        pushup(root);
    }
    L query(int root ,int l , int r){
        pushdown(root);
        if(tree[root].r < l || tree[root].l > r){
            return 0;
        }
        if(tree[root].r <= r && tree[root].l >= l){
            return tree[root].ma;
        }
        L ans = 0;
        ans |= query(root*2,l,r);
        ans |= query(root*2+1,l,r);
        pushup(root);
        return ans ;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            q[i].clear();
        }
        cnt = 0;
        memset(id,-1,sizeof(id));
        for(int i=1;i<=n-1;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            q[v].push_back(u);
            q[u].push_back(v);
        }
        memset(mark,-1,sizeof(mark));
        dfs(1);
        crea(1,1,cnt);
        for(int i=1;i<=m;i++){
            int k ;
            scanf("%d",&k);
            if(k == 1){
                int v,c;
                scanf("%d%d",&v,&c);
                int ll = zg[v].l;
                int rr = zg[v].r;
                upda(1,ll,rr,c);
            }
            else {
                int v;
                scanf("%d",&v);
                int ll = zg[v].l;
                int rr = zg[v].r;
                L res = query(1,ll,rr);
                int ans = 0;
                while(res > 0){
                    ans += (res %2);
                    res >>= 1;
                }
                printf("%d
    ",ans);
            }
        }
    }
    

      

  • 相关阅读:
    pormise的基本用法
    let 与 var 的区别
    字符串
    数组
    Redis 低级数据结构:一、介绍
    Curator使用:(七)分布式Barrier
    Curator使用:(六)分布式计数器
    Curator使用:(五)分布式锁
    Curator使用:(四)Master选举
    Curator使用:(三)事件监听
  • 原文地址:https://www.cnblogs.com/rayrayrainrain/p/6029779.html
Copyright © 2011-2022 走看看