YTU_3309: Lorenzo Von Matterhorn(完全二叉樹 最近公共祖先)
阿新 • • 發佈:2019-02-19
3309: Lorenzo Von Matterhorn
時間限制: 1 Sec 記憶體限制: 128 MB
提交: 6 解決: 6
[提交][狀態][討論版][命題人:acm4302]
題目描述
Barney住在紐約。紐約市有無限數量的路口,路口為從1開始編號的正整數。在路口i和2*i以及i和2*i +1之間存在雙向道路,您可以清楚地看到任意兩個路口之間存在唯一的最短路徑。
最初任何人都可以免費通過所有道路。但是由於SlapsGiving領先於我們,很快就會有q個連續事件發生。有兩種型別的事件:
1.政府制定新規則。規則可以用整數v,u和w表示。作為這一行動的結果,從u到v的最短路徑上的所有道路的通過費用增加了w美元。
2. Barney從路口v移動到路口u那裡是他想擁抱的一個女孩。他總是使用兩個十字路口之間的最短路徑(訪問最小數量的交叉路口或道路)。
政府需要你的計算。每次Barney去擁抱一個女孩時,他應該支付多少錢
輸入
輸入的第一行包含一個整數q(1≤q≤1 000)。
下面q行按時間順序包含有關事件的資訊。每個事件的形式描述
1 v u w如果當政府提出一個新的規則有關從增加從u到v的最短路徑上的所有道路的通過費w美元。
2 v u當Barney從路口v到路口u擁抱一個女孩。
1≤v,u ≤10^18,v ≠ u,1≤ w ≤10^9
輸出
對於第二類事件,按相應事件的時間順序在一行中列印Barney道路的通行費總和。
樣例輸入
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
樣例輸出
94
0
32
#include<bits/stdc++.h> #define rep(i,j,k) for(int i=j;i<k;i++) #define per(i,j,k) for(int i=j;i<=k;i++) #define IO ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0); using namespace std; typedef long long ll; map <ll,ll> mp; void swap(ll a, ll b) { ll c; c=a; a=b; b=c; } void updateL(ll v,ll u ,ll w) { while(v!=u) { if(v<u) swap(v,u); mp[v]+=w; v>>=1; } } void get_ans(ll v,ll u) { ll ans = 0; while(v!=u) { if(v<u) swap(v,u); ans += mp[v]; v>>=1; } cout<<ans<<endl; } int main(void) { IO int n;cin>>n; ll v,u,w; int op; while(n--) { cin>>op; if(op&1) { cin>>v>>u>>w; updateL(v,u,w); } else { cin>>v>>u; get_ans(v,u); } } }