FZU 2277 线段树+DFS序

xiaoxiao2021-02-28  86

题意

对一棵树进行操作,1 v x k代表对根节点v加x,对v的子节点加x-k,对孙子节点加v-2k。2 v代表查询节点V的值。

题解

其实是一个很简单的线段树,对于一次增加操作,节点x增加的值其实就是x-(deep[x]-deep[v])*k。(deep[v]为该次修改的根节点)。查询的时候单点查询,也不用pushdown,直接再递归返回的时候加上中间节点的值就可以了。

注意事项

需要求DFS序,需要特别注意末节点end的位置是pos-1,而不是pos,因为末节点在赋值后pos++了。

代码

#include <iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #include<cmath> #include<queue> #include<string> #include<set> #include<map> #include<bitset> #include<stack> #define UP(i,l,h) for(int i=l;i<h;i++) #define DOWN(i,h,l) for(int i=h-1;i>=l;i--) #define W(a) while(a) #define MEM(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f3f3f3f3f #define LL long long #define MAXN 300010 #define SIZE 95 #define EPS 1e-10 #define MOD 1000000007 #define int LL using namespace std; struct Node{ int num,k; }; Node nodes[MAXN*4]; vector<int> son[MAXN]; int lt,rt,v,k; int st[MAXN],ed[MAXN],dep[MAXN]; int u; int pos,deep; void dfs(int x){ int sz=son[x].size(); st[x]=pos++; dep[x]=deep; deep++; UP(i,0,sz){ dfs(son[x][i]); } deep--; ed[x]=pos-1; } void update(int o,int l,int r){ if(lt<=l&&rt>=r){ nodes[o].num=(nodes[o].num+v+dep[u]*k)%MOD; nodes[o].k=(nodes[o].k+k)%MOD; }else{ int m=l+(r-l)/2; if(lt<=m){ update(o*2,l,m); } if(rt>m){ update(o*2+1,m+1,r); } } } int query(int o,int l,int r){ if(lt<=l&&rt>=r){ return (nodes[o].num-(nodes[o].k*dep[u])%MOD)%MOD; }else{ int m=l+(r-l)/2; if(lt<=m){ return (query(o*2,l,m)+nodes[o].num-(nodes[o].k*dep[u])%MOD)%MOD; }else{ return (query(o*2+1,m+1,r)+nodes[o].num-(nodes[o].k*dep[u])%MOD)%MOD; } } } main(){ int t; scanf("%I64d",&t); W(t--){ MEM(dep,0); int n; scanf("%I64d",&n); UP(i,1,n+1){ son[i].clear(); } pos=1; deep=0; int p; UP(i,1,n){ scanf("%I64d",&p); son[p].push_back(i+1); } dfs(1); MEM(nodes,0); int q; scanf("%I64d",&q); W(q--){ int a; scanf("%I64d",&a); if(a==1){ scanf("%I64d%I64d%I64d",&u,&v,&k); lt=st[u]; rt=ed[u]; update(1,1,n); }else{ scanf("%I64d",&u); lt=rt=st[u]; printf("%I64d\n",(query(1,1,n)+MOD)%MOD); } } } }
转载请注明原文地址: https://www.6miu.com/read-70433.html

最新回复(0)