zoukankan      html  css  js  c++  java
  • UVA

    You are given a tree with N nodes. The tree nodes are numbered from 1 to N and have colors C1, C2,
    . . . , CN initially. You have to handle M instructions on the tree of the following forms:
    • 0 u c: Change the color of node u to c.
    • 1 u v: Output the maximum number of times a color appeared on the unique path from node u
    to node v.
    Input
    The first line of input contains T (1 ≤ T ≤ 10) which is the number of test cases. The first line of each
    test case contains two integers N and M (1 ≤ N, M ≤ 105
    ). Next line contains N space separated
    integers C1, C2, . . . , CN (1 ≤ Ci ≤ 10) denoting the initial colors of the nodes. Each of the next N − 1
    lines contain two integers a and b (1 ≤ a, b ≤ N and a ̸= b) meaning that there is an edge between
    node a and node b. Each of the next M lines contains an instruction of one of the two forms described
    above. For all the instructions: 1 ≤ u, v ≤ N and 1 ≤ c ≤ 10.
    Output
    For each of the second type instruction output the answer in one line.
    Sample Input
    2
    5 6
    3 2 1 2 3
    1 2
    2 3
    2 4
    1 5
    1 3 5
    0 1 1
    0 2 1
    1 3 5
    0 2 4
    1 2 4
    2 1
    5 6
    1 2
    1 2 2
    Sample Output
    2
    3
    1
    1

    题意:给你一颗树,树上的每个节点都有颜色,颜色编号在1-10之间,给出两种操作

    操作一:将树上x点的颜色搞成val

    操作二:求点u到点v路径上最多的颜色有几个

    题解:颜色很少,所以不用树上莫队,可以建10棵线段树,如果一个点的颜色为ai,则在ai编号的线段树上该点为1,其他编号的树上该点为0

    然后每次跑路径的时候跑十遍,记下路径和最大的一种颜色输出,就是答案了,emmm,真暴力啊QAQ

    因为涉及到树上路径,所以树链剖分即可了

    代码如下:

    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define lson root<<1
    #define rson root<<1|1
    using namespace std;
    
    struct seg_tree
    {
        struct node
        {
            int l,r,sum;
        } tr[400040];
    
        void push_up(int root)
        {
            tr[root].sum=tr[lson].sum+tr[rson].sum;
        }
    
        void build(int root,int l,int r)
        {
            if(l==r)
            {
                tr[root].l=l;
                tr[root].r=r;
                return ;
            }
            tr[root].l=l;
            tr[root].r=r;
            int mid=(l+r)>>1;
            build(lson,l,mid);
            build(rson,mid+1,r);
        }
    
        void update(int root,int pos,int val)
        {
            if(tr[root].l==pos&&tr[root].r==pos)
            {
                tr[root].sum=val;
                return ;
            }
            int mid=(tr[root].l+tr[root].r)>>1;
            if(pos<=mid)
            {
                update(lson,pos,val);
            }
            else
            {
                update(rson,pos,val);
            }
            push_up(root);
        }
    
        int query(int root,int l,int r)
        {
            if(tr[root].l==l&&tr[root].r==r)
            {
                return tr[root].sum;
            }
            int mid=(tr[root].l+tr[root].r)>>1;
            if(mid<l)
            {
                return query(rson,l,r);
            }
            else
            {
                if(mid>=r)
                {
                    return query(lson,l,r);
                }
                else
                {
                    return query(lson,l,mid)+query(rson,mid+1,r);
                }
            }
        }
    
        void dfs(int root,int l,int r)
        {
            if(l==r)
            {
                return ;
            }
    
            int mid=(l+r)>>1;
            dfs(lson,l,mid);
            dfs(rson,mid+1,r);
        }
    } tree[11];
    
    vector<int> g[100010];
    int fa[100010],deep[100010],size[100010],son[100010],id[100010],c[100010],w[100010],top[100010],cnt;
    
    void dfs1(int now,int f,int dep)
    {
        fa[now]=f;
        deep[now]=dep;
        size[now]=1;
        int maxson=-1;
        for(int i=0; i<g[now].size(); i++)
        {
            if(g[now][i]==f)
            {
                continue;
            }
            dfs1(g[now][i],now,dep+1);
            size[now]+=size[g[now][i]];
            if(size[g[now][i]]>maxson)
            {
                maxson=size[g[now][i]];
                son[now]=g[now][i];
            }
        }
    }
    
    void dfs2(int now,int topf)
    {
        id[now]=++cnt;
        w[cnt]=c[now];
        top[now]=topf;
        if(!son[now])
        {
            return ;
        }
        dfs2(son[now],topf);
        for(int i=0; i<g[now].size(); i++)
        {
            if(fa[now]==g[now][i]||g[now][i]==son[now])
            {
                continue;
            }
            dfs2(g[now][i],g[now][i]);
        }
    }
    
    void point_update(int u,int val)
    {
        for(int i=1; i<=10; i++)
        {
            if(val==i)
            {
                tree[i].update(1,id[u],1);
            }
            else
            {
                tree[i].update(1,id[u],0);
            }
        }
    }
    
    int path_query(int u,int v,int val)
    {
        int ans=0;
        while(top[u]!=top[v])
        {
            if(deep[top[u]]<deep[top[v]])
            {
                swap(u,v);
            }
            ans+=tree[val].query(1,id[top[u]],id[u]);
            u=fa[top[u]];
        }
        if(deep[u]>deep[v])
        {
            swap(u,v);
        }
        ans+=tree[val].query(1,id[u],id[v]);
        return ans;
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n,m;
            memset(tree,0,sizeof(tree));
            memset(fa,0,sizeof(fa));
            memset(son,0,sizeof(son));
            memset(deep,0,sizeof(deep));
            memset(size,0,sizeof(size));
            memset(id,0,sizeof(id));
            memset(c,0,sizeof(c));
            memset(w,0,sizeof(w));
            memset(top,0,sizeof(top));
            cnt=0;
            for(int i=1;i<=100000;i++)
            {
                g[i].clear();
            }
            scanf("%d%d",&n,&m);
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&c[i]);
            }
            for(int i=1; i<n; i++)
            {
                int from,to;
                scanf("%d%d",&from,&to);
                g[from].push_back(to);
                g[to].push_back(from);
            }
            dfs1(1,0,1);
            dfs2(1,1);
            for(int i=1; i<=10; i++)
            {
                tree[i].build(1,1,n);
            }
            for(int i=1; i<=n; i++)
            {
                tree[w[i]].update(1,i,1);
            }
            for(int i=1; i<=m; i++)
            {
                int kd,l,r;
                scanf("%d%d%d",&kd,&l,&r);
                if(kd==1)
                {
                    int ans=0;
                    for(int j=1; j<=10; j++)
                    {
                        ans=max(ans,path_query(l,r,j));
                    }
                    printf("%d
    ",ans);
                }
                else
                {
                    if(kd==0)
                    {
                        point_update(l,r);
                    }
    
                }
            }
        }
    
    }
  • 相关阅读:
    try {}里有一个 return 语句,那么紧跟在这个 try 后的 finally {}里的 code 会不会被执行,什么时候被执行,在 return 前还是后?
    BigDecimal 使用 静态方法总结
    成员内部类里面为什么不能有静态成员和方法?
    浅谈多态机制的意义及实现
    Java接口中的成员变量的意义
    IDEA 打包和导入 Jar 包
    Java static关键字
    Java this关键字
    Java 匿名对象
    Java JOptionPane 对话框
  • 原文地址:https://www.cnblogs.com/stxy-ferryman/p/9026117.html
Copyright © 2011-2022 走看看