[codeforces] 383C Propagating tree(dfs序+线段树)
Propagating tree
https://ac.nowcoder.com/acm/problem/110318
题意:
给你一棵n个结点的树, 以1为根。每个结点有点权。有m次操作:
1.x结点权值 +val,x的儿子权值 −val,x的孙子们 +val,以此类推。
2.询问x的点权;
题解:
我们首先跑一边dfs序,顺便求除每个结点的深度。
我们把他分成两颗线段树,深度为奇数的在第一颗上,深度为偶数的在第二课上。
我们每次对两颗线段树同时操作。
第一颗线段树只进行+操作,第二棵线段树只-操作。
当我们询问某个点时,我们只需要判断一下这个点的奇偶,决定查询哪颗树即可。
/*Keep on going Never give up*/ //#pragma GCC optimize(3,"Ofast","inline") #include<bits/stdc++.h> //#define int long long #define endl '\n' #define Accepted 0 #define AK main() #define I_can signed using namespace std; const int maxn =4e5+10; const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int inf=0x3f3f3f3f; const ll mod=1e9+7; vector<int> edge[maxn]; int a[maxn]; int in[maxn],out[maxn],cnt; int tree[2][maxn<<2]; int deep[maxn]; void dfs(int u,int fa){ in[u]=++cnt; deep[u]=deep[fa]+1; for(auto i:edge[u]){ if(i==fa) continue; dfs(i,u); } out[u]=cnt; } void push(int node,int x){ if(tree[x][node]){ tree[x][node*2]+=tree[x][node]; tree[x][node*2+1]+=tree[x][node]; tree[x][node]=0; } return; } void update(int node,int l,int r,int start,int ends,int x,int val){ if(start<=l&&ends>=r){ tree[x][node]+=val; //cout<<tree[x][node]<<endl; return; } push(node,x); int mid=(l+r)/2; if(start<=mid) update(node*2,l,mid,start,ends,x,val); if(mid<ends) update(node*2+1,mid+1,r,start,ends,x,val); } int query(int node,int l,int r,int pos,int x){ if(l==r){ //cout<<tree[x][node]<<endl; return tree[x][node]; } push(node,x); int mid=(l+r)/2; if(pos<=mid) return query(node*2,l,mid,pos,x); else return query(node*2+1,mid+1,r,pos,x); } signed main(){ // ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int n,m; cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=0;i<n-1;i++){ int x,y; cin>>x>>y; edge[x].push_back(y); edge[y].push_back(x); } dfs(1,0); //for(int i=1;i<=n;i++) cout<<in[i]<<" "; for(int i=0;i<m;i++){ int opt,x,y; cin>>opt; if(opt==1){ //246 296 cin>>x>>y; //cout<<in[x]<<" "<<out[x]<<endl; update(1,1,n,in[x],out[x],deep[x]&1,y); update(1,1,n,in[x],out[x],!(deep[x]&1),-y); } else{ cin>>x; cout<<query(1,1,n,in[x],deep[x]&1)+a[x]<<endl; } } return 0; }
题解 文章被收录于专栏
主要写一些题目的题解