ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LCA C 求和 求子树权值和 树上节点单点修改 dfs序+树状数组

2022-08-25 04:34:53  阅读:71  来源: 互联网

标签:int res ll cin dfs 树权值 LCA 节点 define


 链接:https://ac.nowcoder.com/acm/problem/204871

来源:牛客网

题目描述

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

给定一个根节点 kkk,每个节点都有一个权值,节点i的权值为 viv_ivi​。

给 mmm 个操作,操作有两种类型:

1 a x :表示将节点 aaa 的权值加上 xxx

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

输入描述:

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

第二行给出 nnn 个正整数,第 iii 个正整数表示第 iii 个节点的权值 valival_ivali​

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

接下来 mmm 行,每行给出一个操作

输出描述:

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

示例1

输入

复制
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

备注:

1≤n,m≤1e6,1≤k≤n1\leq n,m\leq 1e6,1\leq k\leq n1≤n,m≤1e6,1≤k≤n 1≤u,v≤n1\leq u,v \leq n1≤u,v≤n 1≤a≤n1\leq a\leq n1≤a≤n −1e6≤vali,x≤1e6−1e6\leq val_i,x\leq 1e6−1e6≤vali​,x≤1e6 建议使用 scanf 读入

分析

欧拉序:每经过一次该节点记录一次该序列

dfs序:记录入栈和出栈的序列

dfn序:只记录入栈的序列

 

用dfs序,记录每个点入栈是什么时间 l[u] = ++time,出栈是什么时间r[u] = time

在这个时间之内的就是它的子树

 

用树状数组维护区间和

如果 u 的子树增加了x,在[l[u],r[u]]内的区间和也要增加 x

所以直接把x 增加在 l[u] 位置或者 r[u] 位置就可以了

询问 u 子树的权值和就是 query(r[u]) - query(l[u]-1)

 

//-------------------------代码----------------------------

//#define int ll
const int N = 2e6+10;
int n,m,k;
int e[N],ne[N],w[N],h[N],idx,v[N];
void add1(int a,int b) {
    e[idx] = b,ne[idx] = h[a],h[a] = idx ++ ;
}

ll tr[N];
int l[N],r[N],num;

void add(int x,int v) {
    for(;x<=n;x+=lowbit(x)) {tr[x] += v;}
}

ll sum(int x) {
    ll res = 0;for(;x;x-=lowbit(x)) res += tr[x];return res;
}

void dfs(int u,int fa) {
    l[u] = ++ num;
    fe(i,u) {
        if(e[i] != fa) {
            dfs(e[i],u);
        }
    }
    r[u] = num;
}

void solve()
{
    ms(h,-1);
    cin>>n>>m>>k;
    fo(i,1,n) {
        cin>>v[i];
    }
    fo(i,1,n-1) {
        int x,y;cin>>x>>y;
        add1(x,y);add1(y,x);
    }
    dfs(k,0);
    fo(i,1,n) add(l[i],v[i]);
    while(m -- ) {
        int op;cin>>op;
        if(op == 1) {
            int a,x;cin>>a>>x;
            add(l[a],x);
        } else {
            int x;cin>>x;
            cout<<sum(r[x]) - sum(l[x] - 1)<<endl;
        }
    }
}
void main_init() {}
signed main(){
    AC();clapping();TLE;
    cout<<fixed<<setprecision(12);
    main_init();
//  while(cin>>n,n)
//  while(cin>>n>>m,n,m)
//    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

#include<bits/stdc++.h>#define TLE ios::sync_with_stdio(0),cin.tie(0)#define endl "\n"#define FILE "a"#define pb push_back#define gg exit(0);#define rt return;#define bd cout<<"debug"<<endl;#define db(x) cout<<#x<<':'<<x<<endl;#define dbb(i,a) cout<<#i<<':'<<i<<' '<<#a<<':'<<a<<' '<<endl;#define dbbb(i,a,b) cout<<#i<<':'<<i<<' '<<#a<<':'<<a<<' '<<#b<<':'<<b<<endl;#define TIME cout<<"RuningTime: "<<clock()<<"ms\n";#define YES cout<<"YES"<<endl;#define Yes cout<<"Yes"<<endl;#define NO cout<<"NO"<<endl;#define No cout<<"No"<<endl;#define None cout<<-1<<endl;#define el cout<<endl;#define x first#define y second#define V vector#define fo(i,j,n) for(int i = j;i<=n;i++)#define of(i,n,j) for(int i = n;i>=j;i--)#define fe(i,u) for(int i = h[u];~i;i=ne[i])#define all(a) a.begin(),a.end()#define alll(a) a.begin()+1,a.end()#define ms(a,b) memset(a, b, sizeof(a));#define tr_len(u) (tr[u].r - tr[u].l + 1)#define tr_mid (tr[u].l + tr[u].r >> 1)#define ul (u<<1)#define ur (u<<1|1)#define lowbit(x) (x&-x)#define gcd(a,b) __gcd(a,b)#define CLAP 11243using namespace std;void clapping() {#if CLAP == 1srand(time(NULL)+rand());freopen("a.in","r",stdin);freopen("a.out","w",stdout);//freopen("a.in","w",stdout);#endif}template<class T>inline void read(T &res) {    char c;T flag = 1;    while((c = getchar()) < '0' || c > '9') if(c == '-') flag = -1;res = c - '0';    while((c=getchar())>='0'&&c<='9')res=(res<<1)+(res<<3)+(c^48);res*=flag;}typedef pair<int,int> pii;typedef pair<long,long>pll;typedef long long ll;const int inf = 0x3f3f3f3f;const ll INF = 0x3f3f3f3f3f3f3f3fll;const double eps = 1e-8;int dy[] = {1,0,-1,0,1,1,-1,-1};int dx[] = {0,1,0,-1,1,-1,1,-1};ll qmi(ll a,ll b) {int res = 1;for(;b;b>>=1,a = a * a ) {if(b&1) res = res * a;}return res;}template<class T> T exgcd(T a,T b,T &x,T &y) {if(b == 0) {x = 1;y = 0;return a;}ll d = gcd_ed(b,a%b,y,x);y = y - a / b * x;return d;}template<class T> T qmul(T a,T b,T p) {T res = 0;for(;b;b >>= 1,a = (a + a) % p) {res = (res + a) % p;}return res;}/*文档区

*/void AC(){    ////                       _oo0oo_//                      o8888888o//                      88" . "88//                      (| -_- |)//                      0\  =  /0//                    ___/`---'\___//                  .' \\|     |// './/                 / \\|||  :  |||// \//                / _||||| -:- |||||- \//               |   | \\\  -  /// |   |//               | \_|  ''\---/''  |_/ |//               \  .-\__  '-'  ___/-. ///             ___'. .'  /--.--\  `. .'___//          ."" '<  `.___\_<|>_/___.' >' "".//         | | :  `- \`.;`\ _ /`;.`/ - ` : | |//         \  \ `_.   \_ __\ /__ _/   .-` /  ///     =====`-.____`.___ \_____/___.-`___.-'=====//                   佛祖保佑, 永无bug;}

//-------------------------代码----------------------------
//#define int llconst int N = 2e6+10;int n,m,k;int e[N],ne[N],w[N],h[N],idx,v[N];void add1(int a,int b) {    e[idx] = b,ne[idx] = h[a],h[a] = idx ++ ;}
ll tr[N];int l[N],r[N],num;
void add(int x,int v) {    for(;x<=n;x+=lowbit(x)) {tr[x] += v;}}
ll sum(int x) {    ll res = 0;for(;x;x-=lowbit(x)) res += tr[x];return res;}
void dfs(int u,int fa) {    l[u] = ++ num;    fe(i,u) {        if(e[i] != fa) {            dfs(e[i],u);        }    }    r[u] = num;}
void solve(){    ms(h,-1);    cin>>n>>m>>k;    fo(i,1,n) {        cin>>v[i];    }    fo(i,1,n-1) {        int x,y;cin>>x>>y;        add1(x,y);add1(y,x);    }    dfs(k,0);    fo(i,1,n) add(l[i],v[i]);    while(m -- ) {        int op;cin>>op;        if(op == 1) {            int a,x;cin>>a>>x;            add(l[a],x);        } else {            int x;cin>>x;            cout<<sum(r[x]) - sum(l[x] - 1)<<endl;        }    }}void main_init() {}signed main(){AC();clapping();TLE;cout<<fixed<<setprecision(12);main_init();//  while(cin>>n,n)//  while(cin>>n>>m,n,m)//int t;cin>>t;while(t -- )solve();//{solve(); }return 0;}
/*样例区

*/
//------------------------------------------------------------



标签:int,res,ll,cin,dfs,树权值,LCA,节点,define
来源: https://www.cnblogs.com/er007/p/16622928.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有