zoukankan      html  css  js  c++  java
  • DFS序1

    给一棵有根树,这棵树由编号为1..N的N个结点组成。根结点的编号为R。
    每个结点都有一个权值,结点i的权值为vi 。
    接下来有M组操作,操作分为两类:
    1 a x,表示将结点a的权值增加x;
    2 a,表示求结点a的子树上所有结点的权值之和。
    输入格式
    第一行有三个整数N,M和R。
    第二行有N个整数,第i个整数表示vi 。
    在接下来的N-1行中,每行两个整数,表示一条边。
    在接下来的M行中,每行一组操作。
    输出格式
    对于每组2 a操作,输出一个整数,表示「以结点a为根的子树」上所有结点的权值之和。
    样例
    样例输入 1
    10 14 9
    12 -6 -4 -3 12 8 9 6 6 2
    8 2
    2 10
    8 6
    2 7
    7 1
    6 3
    10 9
    2 4
    10 5
    1 4 -1
    2 2
    1 7 -1
    2 10
    1 10 5
    2 1
    1 7 -5
    2 5
    1 1 8
    2 7
    1 8 8
    2 2
    1 5 5
    2 6
    样例输出 1

    21
    34
    12
    12
    23
    31
    4
    1<=N,M<=10^6,1<=R<=N
    -10^6<=vi,x<=10^6

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6 + 6;
    typedef long long ll;
    ll c[maxn], in[maxn], out[maxn], tot, d[maxn], head[maxn], cnt, n, m, r;
    struct node {
        int to, nxt;
    } e[maxn << 1];
    void addedge(int u, int v) {
        e[++tot] = { v, head[u] };
        head[u] = tot;
    }
    void dfs(int u) {
        in[u] = ++cnt;
        for (int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            if (in[v])
                continue;
            dfs(v);
        }
        out[u] = cnt;
    }
    ll lowbit(int x) 
    { 
    	return x & -x; 
    }
    void add(int u, int x) 
    {
        while (u <= n) 
    	{
            c[u] += x;
            u += lowbit(u);
        }
    }
    ll query(int u) {
        ll ret = 0;
        while (u > 0) {
            ret += c[u];
            u -= lowbit(u);
        }
        return ret;
    }
    int main() {
        cin >> n >> m >> r;
        for (int i = 1; i <= n; ++i) cin >> d[i];
        for (int i = 1, a, b; i < n; ++i) 
    	{
            cin >> a >> b;
            addedge(a, b), addedge(b, a);
        }
        dfs(r);
        for (int i = 1; i <= n; ++i) //最始权值 
    	    add(in[i], d[i]);
        for (int i = 1, op, a, x; i <= m; ++i) 
    	{
            cin >> op >> a;
            if (op == 2) 
    		{
                cout << query(out[a]) - query(in[a] - 1) << endl;
            } 
    		else 
    		{
                cin >> x;
                add(in[a], x);
            }
        }
    }
    

      

  • 相关阅读:
    png 图片的缩放
    数据结构>图的最短路径
    2007年7月25日在博客园的排名上升到前400名
    C# 汉字转拼音(全拼)
    修改 Linux 主机名
    C# 事件的继承
    一个实现了 IDisposable 接口的基类
    Windows 防火墙上也有端口映射功能
    网上邻居不能访问的问题
    令网站提速的7大秘方
  • 原文地址:https://www.cnblogs.com/cutemush/p/11795063.html
Copyright © 2011-2022 走看看