51nod_1199 树的先跟遍历+区间更新树状数组
题目是中文,所以不讲题意
做法顺序如下:
- 使用先跟遍历,把整棵树平铺到一维平面中
- 使用自己整的区间更新树状数组模板进行相关操作。
- http://www.cnblogs.com/rikka/p/7359185.html
放代码如下:
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 6 /* 7 *常量MAXN用于设定树状数组的尺寸大小 8 */ 9 const long long MAXN=500233; 10 class TreeLikeArray 11 { 12 public: 13 /* 14 *数组c1用来储存A[i]-A[i-1]; 15 */ 16 long long c1[MAXN]; 17 /* 18 *数组c2用来储存(A[i]-A[i-1])*(i-1); 19 *或认为用于储存(i-1)*c1[i]; 20 *两种实现方式完全等价 21 */ 22 long long c2[MAXN]; 23 /* 24 *树状数组的常规操作,参数要求传入数组并指明更新位置,以及更新参数。 25 *树状数组基础底层操作 26 */ 27 void add(long long array[],long long pos,long long key) 28 { 29 while(pos<MAXN) 30 { 31 array[pos]+=key; 32 pos+=pos&(-pos); 33 } 34 } 35 /* 36 *特别树状数组单点更新操作,要求传入位置和参数 37 */ 38 void add(long long pos,long long key) 39 { 40 41 add(c1,pos,key); 42 add(c1,pos+1,-key); 43 add(c2,pos,(pos-1)*key); 44 add(c2,pos+1,-pos*key); 45 46 47 } 48 /* 49 *特别树状数组多点更新操作,要求传入起始位置、终止位置和参数 50 *该操作将会使得[pos1,pos2]闭区间内所有元素得到更新 51 */ 52 void add(long long pos1,long long pos2,long long key) 53 { 54 add(c1,pos1,key); 55 add(c1,pos2+1,-key); 56 add(c2,pos1,(pos1-1)*key); 57 add(c2,pos2+1,-pos2*key); 58 } 59 /* 60 *树状数组的常规操作,参数要求传入数组并指明求和位置 61 *树状数组基础底层操作 62 */ 63 long long getSum(long long array[],long long pos) 64 { 65 long long ret=0; 66 while(pos>0) 67 { 68 ret+=array[pos]; 69 pos-=pos&(-pos); 70 }return ret; 71 } 72 /* 73 *从起始节点到目标节点闭区间求和[0,i] 74 */ 75 long long getSum(long long pos) 76 { 77 return pos*getSum(c1,pos)-getSum(c2,pos); 78 } 79 /* 80 *求[pos1,pos2]闭区间内元素和 81 */ 82 long long getSum(long long pos1,long long pos2) 83 { 84 return getSum(pos2)-getSum(pos1-1); 85 } 86 /* 87 *求pos单个元素的值 88 */ 89 long long getSingle(long long pos) 90 { 91 return getSum(pos,pos); 92 } 93 }; 94 TreeLikeArray TLA; 95 long long mapp[MAXN]; 96 long long son[MAXN]; 97 long long power[MAXN]; 98 vector<long long >G[MAXN]; 99 long long n,m; 100 101 long long point=1; 102 void dfs(long long x) 103 { 104 mapp[x]=point; 105 for(int i=0;i<G[x].size();++i) 106 { 107 point++; 108 dfs(G[x][i]); 109 } 110 son[x]=point; 111 } 112 113 void init() 114 { 115 cin>>n>>m; 116 for(int i=1;i<n;++i) 117 { 118 long long a,p; 119 cin>>a>>p; 120 G[a].push_back(i); 121 power[i]=p; 122 } 123 dfs(0); 124 for(int i=0;i<n;++i) 125 { 126 TLA.add(mapp[i],power[i]); 127 } 128 } 129 130 int main() 131 { 132 cin.sync_with_stdio(false); 133 134 init(); 135 for(int i=0;i<m;++i) 136 { 137 char c; 138 int a,b,z; 139 cin>>c>>a>>b>>z; 140 if(c=='S') 141 { 142 long long x=TLA.getSingle(mapp[a]); 143 if(x<b)TLA.add(mapp[a],z); 144 }else 145 { 146 long long summ=TLA.getSum(mapp[a],son[a]); 147 if(summ<b*(son[a]-mapp[a]+1))TLA.add(mapp[a],son[a],z); 148 } 149 } 150 for(int i=0;i<n;++i) 151 { 152 cout<<TLA.getSingle(mapp[i])<<endl; 153 } 154 155 return 0; 156 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 《HelloGitHub》第 106 期
· 数据库服务器 SQL Server 版本升级公告
· 深入理解Mybatis分库分表执行原理
· 使用 Dify + LLM 构建精确任务处理应用