您的位置:首页 > 其它

Codeforces Round #362 (Div. 1) A (696A) Lorenzo Von Matterhorn (LCA)

2016-07-15 11:13 309 查看
A. Lorenzo Von Matterhorn

time limit per test
1 second

memory limit per test
256 megabytes

input
standard input

output
standard output

Barney lives in NYC. NYC has infinite number of intersections numbered with positive integers starting from 1. There exists a bidirectional road between intersectionsi and2i and
another road betweeni and2i + 1 for every positive integeri. You can clearly see that there exists a unique shortest path between any two intersections.



Initially anyone can pass any road for free. But since SlapsGiving is ahead of us, there willq consecutive events happen soon. There are two types of events:

1. Government makes a new rule. A rule can be denoted by integers
v, u and
w. As the result of this action, the passing fee of all roads on the shortest path fromu tov increases byw dollars.

2. Barney starts moving from some intersection v and goes to intersectionu where there's a girl he wants to cuddle (using his fake name Lorenzo Von Matterhorn). He always uses
the shortest path (visiting minimum number of intersections or roads) between two intersections.

Government needs your calculations. For each time Barney goes to cuddle a girl, you need to tell the government how much money he should pay (sum of passing fee of all roads he passes).

Input
The first line of input contains a single integer q (1 ≤ q ≤ 1 000).

The next q lines contain the information about the events in chronological order. Each event is described in form1v
uw if it's an event when government makes a new rule about increasing the passing fee of all roads on the shortest path fromu tov
byw dollars, or in form2
v u if it's an event when Barnie goes to cuddle from the intersectionv to the intersectionu.

1 ≤ v, u ≤ 1018, v ≠ u, 1 ≤ w ≤ 109 states for every description line.

Output
For each event of second type print the sum of passing fee of all roads Barney passes in this event, in one line. Print the answers in chronological order of corresponding events.

Example

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


Note
In the example testcase:

Here are the intersections used:



Intersections on the path are 3,
1, 2 and 4.
Intersections on the path are 4,
2 and 1.
Intersections on the path are only 3 and
6.
Intersections on the path are 4,
2, 1 and 3. Passing fee of roads on the path are32,32 and
30 in order. So answer equals to32 + 32 + 30 = 94.
Intersections on the path are 6,
3 and 1.
Intersections on the path are 3 and
7. Passing fee of the road between them is 0.
Intersections on the path are 2 and
4. Passing fee of the road between them is 32 (increased by30 in the first event and by2 in the second).

题目大意:

    有10^18个城市,按照城市n的儿子是n*2,n*2+1建立一棵完全二叉树。有2种操作:1、使a,b两个城市之间最短路上的每条道路的路费加x(初始全为0)。2、求从a到b走最短路所需要的路费。

解题思路:

    参考了一下官方题解:http://codeforces.com/blog/entry/46031

    LCA(最近公共祖先)问题。用一个map[i]储存以i为子节点边的花费,在LCA过程中实现路费的更新与计算。

附AC代码:

#include <iostream>
#include <algorithm>
#include <string>
#include <cstdio>
#include <map>
using namespace std;
#define LL long long

map<LL,LL> m;

LL lca(LL u,LL v,int x=0)
{
LL ans=0;
while(u!=v)
{
if(v<u)
swap(u,v);
if(m.find(v)!=m.end())//花费为0
ans+=m[v];
if(x)//更新路费
m[v]+=x;
v=v>>1;//向上查询
}
return ans;
}

int main()
{
int q;
scanf("%d",&q);
while(q--)
{
int op,x;
LL u,v;
scanf("%d%lld%lld",&op,&u,&v);
if(op==1)
{
scanf("%d",&x);
lca(u,v,x);
}
else printf("%lld\n",lca(u,v));
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: