zoukankan      html  css  js  c++  java
  • Z

    Z - New Year Tree

     CodeForces - 620E 

    这个题目还没有写,先想想思路,我觉得这个题目应该可以用bitset,

    首先这个肯定是用dfs序把这个树转化成线段树,也就是二叉树。

    然后就是一个区间修改和区间查询。这个区间查询时查询这个区间的种类数。

    这个之前写过几个题目也是查区间种类数的

    G. Yash And Trees 线段树 bitset

    20190709 暑训 区间种类数 莫队的学习

    莫队和权值线段树应该都是不支持修改的,所以这个题目用不上,

    然后就是这个高端压位卡常容器bitset 我觉得这个题目应该可以用到。

    #include <cstring>
    #include <queue>
    #include <cstdlib>
    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <bitset>
    #include <algorithm>
    #include <map>
    #include <vector>
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    typedef long long ll;
    typedef bitset<100> bit;
    const int maxn = 4e5 + 10;
    vector<int>G[maxn];
    ll el[maxn], er[maxn], a[maxn], tot, num[maxn];
    
    void dfs(int u,int pre)
    {
        el[u] = ++tot;
        num[tot] = u;
        for(int i=0;i<G[u].size();i++)
        {
            int v = G[u][i];
            if (v == pre) continue;
            dfs(v, u);
        }
        er[u] = tot;
    }
    
    bit tree[maxn * 8];
    ll lazy[maxn * 8];
    
    void build(int id,int l,int r)
    {
        lazy[id] = 0;
        if(l==r)
        {
            tree[id].reset();
            tree[id] = (1ll << (a[num[l]] - 1));
            return;
        }
        int mid=(l + r) >> 1;
        build(id << 1, l, mid);
        build(id << 1 | 1, mid + 1, r);
        tree[id] = tree[id << 1] | tree[id << 1 | 1];
    }
    
    void push_down(int id)
    {
        if(lazy[id]!=0)
        {
            tree[id << 1].reset(); tree[id << 1 | 1].reset();
            tree[id << 1] = (1ll << (lazy[id] - 1));
            tree[id << 1 | 1] = (1ll << (lazy[id] - 1));
            lazy[id << 1] = lazy[id << 1 | 1] = lazy[id];
            lazy[id] = 0;
        }
    }
    
    void update(int id,int l,int r,int x,int y,int val)
    {
        if(x<=l&&y>=r)
        {
            tree[id].reset();
            tree[id] = (1ll << (val - 1));
            lazy[id] = val;
            return;
        }
        push_down(id);
        int mid = (l + r) >> 1;
        if (x <= mid) update(id << 1, l, mid, x, y, val);
        if (y > mid) update(id << 1 | 1, mid + 1, r, x, y, val);
        tree[id] = tree[id << 1] | tree[id << 1 | 1];
    }
    
    bit query(int id,int l,int r,int x,int y)
    {
        if (x <= l && y >= r) return tree[id];
        int mid = (l + r) >> 1;
        bit ans; 
        ans.reset();
        push_down(id);
        if (x <= mid) ans = query(id << 1, l, mid, x, y);
        if (y > mid) ans |= query(id << 1 | 1, mid + 1, r, x, y);
        return ans;
    }
    
    int main() {
        int n, m;
        tot = 0;
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
        for (int i = 1; i < n; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        dfs(1, -1);
        build(1, 1, n);
        while (m--) {
            int opt, v, x;
            scanf("%d", &opt);
            if (opt == 1) {
                scanf("%d%d", &v, &x);
                update(1, 1, n, el[v], er[v], x);
            }
            else {
                scanf("%d", &v);
                bit ans = query(1, 1, n, el[v], er[v]);
                printf("%d
    ", ans.count());
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    poj 3528 (三维几何求凸包+凸包表面积)
    dijkstra模板(好像是斐波那契额堆优化,但我为什么看起来像优先队列优化,和spfa一样)
    最大空凸包模板
    ICPC 2017–2018, NEERC, Northern Subregional Contest St Petersburg, November 4, 2017 I题
    hdu 5248 序列变换
    hdu 2063(二分图模板测试)
    组合数
    85. Maximal Rectangle 由1拼出的最大矩形
    750. Number Of Corner Rectangles四周是点的矩形个数
    801. Minimum Swaps To Make Sequences Increasing 为使两个数组严格递增,所需要的最小交换次数
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/11310680.html
Copyright © 2011-2022 走看看