https://codeforces.com/group/qWc0vtZbjV/contest/697/problem/C
思路:开始第一眼是树剖,看了一下发现1e18,就尝试了一下离散化。做了发现连边的对应关系不对了。然而如果是完全二叉树1e18也建立不下。
因此不考虑建树。对着采用朴素lca的思想往上跳,每个点最多跳60次,然后跳的过程中更新该节点的权值。
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5;
typedef long long LL;
map<LL,LL>map1;
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
LL q;cin>>q;
while(q--){
LL op,u,v,cost;
cin>>op;
if(op==1){
cin>>u>>v>>cost;
if(u<v) swap(u,v);
while(u!=v){
map1[u]+=cost;
u/=2;
if(u<v) swap(u,v);
}
}
else if(op==2){
cin>>u>>v;
if(u<v) swap(u,v);
LL sum=0;
while(u!=v){
sum+=map1[u];
u/=2;
if(u<v) swap(u,v);
}
cout<<sum<<endl;
}
}
return 0;
}