zoukankan      html  css  js  c++  java
  • 牛客小白月赛24—I.求和

    牛客小白月赛24—I.求和

    题目描述

    已知有(n)个节点,有(n-1)条边,形成一个树的结构。

    给定一个根节点(k),每个节点都有一个权值,节点(i)的权值为(v_i)

    (m)个操作,操作有两种类型:

    1 a x : 表示将节点(a)的权值加上x

    2 a : 表示求(a)节点的子树上所有节点的和(包括(a)节点本身)

    输入描述

    第一行给出三个正整数 (n,m,k),表示树的节点数、操作次数、和这颗树的根节点,

    第二行给出(n)个正整数,第(i)个正整数表示第(i)个节点的权值(val_i)

    下面(n-1)行每行两个正整数(u,v),表示边的两个端点

    接下来(m)行,每行给出一个操作

    输出描述

    对于每个类型为 2 的操作,输出一行一个正整数,表示以 (a) 为根的子树的所有节点的权值和

    样例输入

    5 6 1
    1 2 3 4 5
    1 3
    1 2
    2 4
    2 5
    1 2 10
    1 3 10
    1 4 5
    1 5 1
    2 3
    2 2
    

    样例输出

    13
    27
    

    备注

    (1leq n,mleq 1e6,1leq k leq n)

    (1leq u,v leq n)

    (1leq a leq n)

    (-1e6leq val_i,x leq 1e6)

    建议使用scanf读入

    思路

    DFS序加树状数组或者线段树维护前缀和

    关于DFS序见:https://www.cnblogs.com/LeafLove/p/12730685.html

    Code

    #include <bits/stdc++.h>
    #define CSE(x,y) memset(x,y,sizeof(x))
    #define INF 0x3f3f3f3f
    #define FAST ios::sync_with_stdio(false);cin.tie(0);
    using namespace std;
    
    typedef long long ll;
    typedef pair<int,int> pii;
    typedef pair<ll , ll> pll;
    
    const int maxn = 2000111;
    //graph_describe
    int v[maxn],u[maxn],first[maxn],nxt[maxn],n,m,k,cnt;
    ll val[maxn];
    //dfs_order
    int in[maxn],out[maxn],order;
    //Tree_array
    ll sum[maxn];
    
    void add(int a,int b) {
    	cnt++;
        u[cnt] = a; v[cnt] = b; nxt[cnt] = first[u[cnt]]; first[u[cnt]] = cnt;
        return;
    }
    
    void dfs(int be,int fa) {
        in[be] = ++order;
        for(int i=first[be];i!=-1;i=nxt[i]) {
            if(v[i] != fa) {
                dfs(v[i],be);
            }
        }
        out[be] = order;
        return;
    }
    
    int lowbit(int x) { return x & (-x);}
    ll get_ans(int x) {
    	ll ans = 0; while(x) {ans += sum[x];x -= lowbit(x);}
        return ans;
    }
    void update(int x,ll w) {
        while(x<=n) { sum[x] += w; x += lowbit(x);}
        return;
    }
    
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("in.in","r",stdin);
    #endif
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=n;i++) {
            scanf("%lld", &val[i]);
        }
        for(int i=1;i<=n;i++) first[i] = -1;
    	for(int i=1;i<n;i++) {
    	    int a,b;
    	    scanf("%d%d",&a,&b);
    	    add(a,b); add(b,a);
    	}
        dfs(k,-1);
        for(int i=1; i<=n; i++) {
            update(in[i],val[i]);
        }
        while(m--){
            int d,a;
            scanf("%d%d",&d,&a);
            if(d==1) {
                ll x;
                scanf("%lld",&x);
                update(in[a],x);
            }
            else
            {
                printf("%lld
    ",get_ans(out[a]) - get_ans(in[a] - 1));
            }
        }
        return 0;
    }
    

    第一次接触这种题时,真的是被这个做法深深吸引了

  • 相关阅读:
    TCO 2013 2A
    matlab 中的fmincon参数设定问题
    一步步写自己SqlHelper类库(四):Connection对象
    珠海立方科技实习总结
    Web Services 应用开发学习笔记(三):XML模式定义
    C#笔记(一):类型,泛型,集合
    Web Services 应用开发学习笔记(二):XML文档类型定义
    一步步写自己SqlHelper类库(三):连接字符串
    一步步写自己SqlHelper类库(二):.NET Framework 数据提供程序
    (Joomla)多功能健康模块
  • 原文地址:https://www.cnblogs.com/LeafLove/p/12731495.html
Copyright © 2011-2022 走看看