Codeforces 697C (LCA)
input
7
1 3 4 30
1 4 1 2
1 3 6 8
2 4 3
1 6 1 40
2 3 7
2 2 4
output
94
0
32
题意:根据题目第一段描述,i->2i、i->2i+1之间有直接连通路,可以得到如下图所示的二叉树。
有两种操作:
第一种:把两个点u,v之间所有的边权值都 +w ;
第二种:求出u,v两点之间的路径权值和。
思路:每次操作都查找两点的最近的公共祖先,查找的同时更新路径权值或者求最短路径代价。
#include <iostream>
#include <map>
using namespace std;
map<long long, long long> mp;
int main() {
int q;
cin >> q;
for(int i = 0; i < q; i++) {
int t;
cin >> t;
if(t == 1) {
long long v, u, w;
cin >> v >> u >> w;
while(v != u) {
if(v < u)
swap(v, u);
mp[v] += w;
v /= 2;
}
}
else {
long long v, u;
cin >> v >> u;
long long ans = 0;
while(v != u) {
if(v < u)
swap(v, u);
ans += mp[v];
v /= 2;
}
cout << ans << '\n';
}
}
return 0;
}