题目:http://codeforces.com/problemset/problem/697/C
题意:
一颗二叉树;
操作1:u->v路径上所有边权值+w
操作2:计算u->v路径权值和
分析:
一开始写了状压,毕竟深度最多60,0向左走,1向右走,写太长了放弃了。
然后,考虑到q很小,只有1e3,实际上有用的边也很少;
所有,直接用map存边权。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int tmax=1e3+5;
map<ll,ll> MM;
void init(ll u,ll v,ll w)
{
while(u!=v)
{
if(log(u)>log(v))
{
MM[u]+=w;
u/=2;
}
else{
MM[v]+=w;
v/=2;
}
}
return;
}
ll work(ll u,ll v)
{
ll ans=0;
while(u!=v)
{
if(log(u)>log(v))
{
ans+=MM[u];
u/=2;
}
else{
ans+=MM[v];
v/=2;
}
}
return ans;
}
int main()
{
int q,i,kind;
cin>>q;
ll u,v,w;
for(i=1;i<=q;i++)
{
scanf("%d",&kind);
if(kind==1)
{
scanf("%I64d%I64d%I64d",&u,&v,&w);
init(u,v,w);
}
else{
scanf("%I64d%I64d",&u,&v);
printf("%I64d\n",work(u,v));
}
}
return 0;
}