cf602e New Year Tree dfs序+二进制+线段树区间修改

本文介绍了使用C++实现的图遍历算法DFS,并通过树状数组进行节点值的更新与查询操作。详细阐述了算法实现过程、优化技巧以及应用案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/* ***********************************************
Author        :Maltub
Email         :xiang578@foxmail.com
Blog          :htttp://www.xiang578.top
************************************************ */

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
//#include <bits/stdc++.h>
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define pb push_back
using namespace std;
typedef vector<int> VI;
typedef long long ll;
const ll mod=1000000007;
const int N=4*100000+10;
int n,m,cnt,st[N],ed[N],vis[N],b[2*N],a[N];
ll ans;
vector<int>edge[N];
struct Tree
{
    int l,r,f;
    ll now;
}tree[10*N];

void dfs(int x)
{
    vis[x]=1;
    st[x]=cnt;
    b[cnt]=a[x];
    cnt++;
    for(int i=0;i<edge[x].size();i++)
    {
        int y=edge[x][i];
        if(!vis[y])
            dfs(y);
    }
    ed[x]=cnt;
    b[cnt]=a[x];
    cnt++;
}

void build(int o,int l,int r)
{
    tree[o].l=l;
    tree[o].r=r;
    tree[o].f=0;
    if(l==r)
    {
        tree[o].now=(long long)1<<(long long)b[l];
    }
    else
    {
        int mid=(l+r)/2;
        build(o*2,l,mid);
        build(o*2+1,mid+1,r);
        tree[o].now=tree[o*2].now|tree[o*2+1].now;
    }
}

void pushdown(int o)
{
    if(tree[o].f!=0)
    {
        tree[o*2].f=tree[o*2+1].f=tree[o].f;
        tree[o].f=0;
        tree[o*2].now=tree[o*2+1].now=tree[o].now;
    }
}

void update(int o,int l,int r,int val)
{
    if(l<=tree[o].l&&tree[o].r<=r)
    {
        tree[o].f=val;
        tree[o].now=(long long)1<<(long long)val;
    }
    else
    {
        pushdown(o);
        int mid=(tree[o].l+tree[o].r)/2;
        if(l<=mid)  update(o*2,l,r,val);
        if(r>mid) update(o*2+1,l,r,val);
        tree[o].now=tree[o*2].now|tree[o*2+1].now;
    }
}

void query(int o,int l,int r)
{
    if(tree[o].f!=0)
    {
        ans=ans|tree[o].now;
    }
    else if(l<=tree[o].l&&tree[o].r<=r)
    {
       ans=ans|tree[o].now;
    }
    else
    {
        int mid=(tree[o].l+tree[o].r)/2;
        if(l<=mid) query(o*2,l,r);
        if(r>mid) query(o*2+1,l,r);
    }
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int i,u,v,c,t;
    while(~scanf("%d%d",&n,&m))
    {
        for(i=1;i<=n;i++)
            edge[i].clear();
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(i=1;i<n;i++)
        {
            scanf("%d%d",&u,&v);
            edge[u].pb(v);
            edge[v].pb(u);
        }
        memset(vis,0,sizeof(vis));
        cnt=1;
        dfs(1);
        build(1,1,cnt-1);
        for(i=0;i<m;i++)
        {
            scanf("%d",&c);
            if(c==1)
            {
                scanf("%d%d",&u,&v);
                update(1,st[u],ed[u],v);
            }
            else
            {
                scanf("%d",&t);

                ans=0;
                query(1,st[t],ed[t]);
                u=0;
                while(ans)
                {
                    u+=ans%2;
                    ans/=2;
                }
                printf("%d\n",u);
            }
        }
    }
    return 0;
}
/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAA8AKADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDU8L+GNAuPCejTTaHpkksljA7u9pGWZiikkkjkmrWr+BdC1DR7u0ttJ020nliKxzx2kYZG7HO31q54R/5E3Q/+wfb/APota2xQB478MItIlub3wvr2h6c+qWbsUee1jZ3UH5lJI5IPI9j6CvTR4Q8Nf9C7pP8A4BR//E1wPxR0S50nUbPxto42XNq6i5wOo6Kx9v4T7EV6L4d1u28RaHa6paH93OmSueUboyn3BoAjHhDwz/0Lukf+AUf/AMTTh4P8Mf8AQuaR/wCAMf8A8TWwKJJY4InllYIiAszHsBQBkjwd4Y/6FzSP/AGL/wCJp48HeF/+hb0f/wAAYv8A4mrMeuaVI7Imo2rMpKkCUHBGM/kSB9eOtaKMrjKsCPY0AY48G+F/+hb0f/wBi/8AiaePBnhb/oWtH/8AAGL/AOJqj4m8bab4ZULO4aUjIXIz1AwBnLE57ZwME4BGafhT4i6f4kvDbArG33VPJBbrjdgDp7DnjmgDcHgzwt/0LWj/APgDF/8AE08eC/Cv/QtaN/4ARf8AxNbQphuYFJBlTcFL7QcnaMZOPTkfnQBlDwV4V/6FnRv/AAAi/wDiacPBXhT/AKFnRv8AwAi/+JrYgmiuIUmhkSSJxlXRgVYeoI60+SWOCMySuqIOrMcCgDHHgnwp/wBCxov/AIARf/E04eCPCf8A0LGi/wDgBF/8TWlZajZahGJLO7hnQ9DG4b+X0P5VdFAGGPBHhP8A6FfRf/BfF/8AE04eB/CX/Qr6J/4L4v8A4mtwU8UAYQ8D+Ev+hW0T/wAF8X/xNY/jHwb4XtfA/iC4t/DejwzxabcPHJHYxKyMImIIIXIIPeu4FYfjj/kn3iT/ALBV1/6KagDkvCP/ACJmhf8AYPt//Ra1tisXwj/yJmhf9g+3/wDRa1tigCO6tIL6zmtLmMSQTIY5EPRlIwRXl0eheIvhY73uju+saE533VoV2yR/7YxntjJHpyOMj1gVyHiPxfLHrMfhfQEE+uXC8yMMxWi9S7+4HOPp6gEArv8AEBPENrbWXg8G41S7UlmlQhbJeheT3HYc5PrxnkfiprOo6fY6V4civprqYhTLOQA0rKcDIH+1g/h3rpY/hSNPubO/0TX7zT9TQH7Tc7RILgnkkoSB17cjHvzXmHxPg1mx8VR/2pfRXU6Rq0c8MXlZ7525ODkdqANHR/hPrupaYuoW18kcjZKBiRuHUHP1ruPBNj4i8JadqS6wXKKCyPIS65AJyMZOMZJ6ZOBXmul6r4/0XTPttot+NOhJLMVLRgZ3flz+tdFJ8VL7XvD09rc6U0jQqGuJY2AAX156fPt/KgDO0e3fxd4sutT1IGWCFiFE/CDnq/PQf3R1PAwBgc3rnleH/Gn2nS5dscUyyRFTgrjGcgdO/A6dKTw9rV5bXUdpa2gnuZLjfskYfPxwpJGRhsngjk07xfousWN4txq5UTTBWVPMLEbhnGSO3TvzQB6r8Qvidc6XBY2mmMwuLiBZXYEcBh7rnPvx9K4a5k8YQaMuqXdw6RH96kZByFIxvQ9vQgdjjocVzUSz6nq1gLq75O1EZdq7QOmPyxn1r1TxV4IitfBkV/NqGr3eEyi3V38qscbVVAMDOSD9KAOi+GnjC3utMkfUryztWJzIHdY1ZsA7xuIPI6/h+PI/Ff4lpqLLo2h3itbjPnTQyZV/QZH5+xArjvD8mkWvhDVNTudKgubmJ1gi8xd2zcSQ5B4PYV1PwptPDCw3l7qeoWLai22S3t5GVCrDJwoPfPGBQByfwz1dNH8ZW1zMLuSNATsto2kdvYKOucmvoQfEC6n4sfBXiaY9jNaLAp/Fm/pXinwvYr8VxE2BvleXI9Bk/wAjX1EKAOKHiPx1c8W3gWO3B6Pd6rGP/HVBNOH/AAs657eFrFD6+fM4/kK7UU8UAV9NjvItOgTUZoprxUAmkiTYrN3IHYVm+OP+SfeJf+wVdf8Aopq3RWF45/5J94l/7BV1/wCimoA5Pwj/AMiZoX/YPt//AEWtbYrF8If8iZoX/YPt/wD0WtbYoA5Lxv4yTw7ZLZ6eFudcumEVrbJ8zBj/ABMPTkYHfj3qXwJ4P/4Rqwkub5/tGtXp8y8uGO45PO0H0B/M/hjivA0Sa58YvEeruokS1aRYmPODu2KR/wABVvzr2MUAKK8n+NnhyW+srXWLdOLSNxOfUZXb/wCzV6yKJYIriFopkV43GGVhkEUAea+AvEei6p8Pl02/uoophCY7hWOOMlFP5BTXl/h63e/8V6nbJAktreyMs8CPtKoWL5B7BSoz7fWu78S/BIS3Rn8PXXkIwAMMpyAcYOD74z+Jrovh58Ml8KySXuoSx3F433cDhBgg898gmgDxyyjj8LeIDPf2MkyKoVwTg7yu113Dhc5ZlPJ4X1NQeK/EV94u1fzEifyz91VXbuORuYgcdl/75HfmvpLUvBmkarJvnibdyMZypUjlSOhXPPPIPQiqth8O9EsriGZYVYxHIV0V93AGCWBPGMggg9skcUAeH+LvDT+GhoV9cpObadY/McdU2qA6gHByeTyPT3r0LXfFdnrXw2KCSEykFpjFJuMcgjMmV9hNsGOflJ+o9D8R+GNO8S6I+mXkCmLH7vb8pQjpg9q8lsfgdqMd35U14rWqyKTlzhlAyeB6tgdsDJ64oAh+G3gKLxF4ekhvGngtJXlaVQv+t+VFTnoCrCU/itX9U/Z8jW0eTTdZfzkTOyaLIY4HcdP4vXtXsGh6JaaDp8dpaIAFUKzkDc55JJx6ksfTk4xWoKAPjOG013w54sktLF2XVbSQxhoDnPbjPUEGvrXwdNqU/hTT5NYSVNQMWZxKu1t2e4rg9b+Dpu/Fqa/puqeUzzeZPDKhO4FskBh/skgcdhXrCZ2jdjPfFADhTxTRTxQA4VheOf8AknviX/sFXX/opq3hWF45/wCSe+Jf+wVdf+imoA5Pwh/yJehf9g63/wDRa1pahdrp+l3d6/3beF5Tn0VSf6V4Bpvxi8Q6Xplpp8FnpjRWsKQoXikLFVUKM4cc4FM1b4v+IdY0i602e102OG5jMTtFHIGCnrjLkfpQB3XwNs2GharqUmS91dBCx6nYuc/m5r1YV8z+G/ijrXhbRY9LsLPTnhRmbfNG5diTnkhwPbp2rX/4Xp4n/wCfDSP+/Mv/AMcoA+hBTxXzz/wvbxP/AM+Gkf8AfmX/AOOUv/C9/FH/AD4aP/35l/8AjlAH0QKeK+df+F8+KP8Anw0f/vzL/wDHKX/hfXin/nw0f/vzL/8AHKAPosU8V85f8L88U/8APho3/fmX/wCOUv8Awv3xV/0D9G/78y//ABygD6PFPFfN3/C//FX/AED9G/78y/8Axyl/4aB8V/8AQP0X/vzL/wDHKAPpIU8V81/8NBeK/wDoH6L/AN+Zf/jlL/w0J4s/6B+i/wDfmX/45QB9LCnivmj/AIaF8W/9A7RP+/Mv/wAco/4aH8W/9A7RP+/Ev/xygD6ZFPFfMv8Aw0R4u/6B2if9+Jf/AI7S/wDDRXi7/oHaJ/34l/8AjtAH04KwvHP/ACT3xL/2Crr/ANFNXgP/AA0X4v8A+gdof/fiX/47VTVvj34p1jRr7S7iw0ZYLy3kt5GjhlDBXUqSMyEZwfQ0Af/Z
最新发布
06-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值