题意:
给出一棵以 节点1 为root的完美二叉树,
有两个操作,
1操作,u 到v 上每条边的权值 +w;
2操作,计算u 到v 上的最短路径下的权值;
思路:
无论是更新还是求值都能看到是对于经过LCA的,
所以对于每个点只需要val[ v ] = weight[ Father[v] - v ]就够了。
无论更新还是查询每次两个节点往上更新就好了,直到遇到LCA。
点最大1e18,层数<50(2^50 = 1024 ^ 5 > 1e20)
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
map<LL, LL>val;
int main(){
int n, op;
LL u, v, w, OldValue, NewValue, Sum;
scanf("%d", &n);
while(n--){
scanf("%d%I64d%I64d", &op, &u, &v);
if(op == 1){
scanf("%I64d", &w);
while(u != v){
if(u > v){
if(val.find(u) != val.end()) OldValue = val[u];
else OldValue = 0LL;
NewValue = OldValue + w;
val[u] = NewValue;
u = u >> 1;
}
else{
if(val.find(v) != val.end()) OldValue = val[v];
else OldValue = 0LL;
NewValue = OldValue + w;
val[v] = NewValue;
v = v >> 1;
}
}
}
else{
Sum = 0;
while(u != v){
if(u > v){
if(val.find(u) != val.end()) Sum = Sum + val[u];
u = u >> 1;
}
else{
if(val.find(v) != val.end()) Sum = Sum + val[v];
v = v >> 1;
}
}
printf("%I64d\n", Sum);
}
}
return 0;
}