1. 程式人生 > >Codeforces 696A Lorenzo Von Matterhorn(LCA)

Codeforces 696A Lorenzo Von Matterhorn(LCA)

題意:

給你一棵樹,其實就是按照線段樹的方法建的樹,有兩種操作,將u到v的路徑上的邊權全部加w,然後詢問從u到v的路徑上的邊權和。

解法:

因為節點的編號很大,所以不能直接建樹,但是可以知道,這棵樹的最大深度也就是62層,所以我們可以用map來儲存邊權,或者把邊權放在點權上,就像樹鏈剖分那樣,每次操作時就可以暴力的向上更新,因為最多1000次操作,哪怕每次都是最深的節點,也最多向上63次,總體的複雜度是可以接受的

//  Created by  CQU_CST_WuErli
//  Copyright (c) 2016 CQU_CST_WuErli. All rights reserved.
// //#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <cctype> #include <cmath> #include <string> #include <vector> #include <map> #include <queue> #include <stack>
#include <set> #include <algorithm> #include <sstream> #define CLR(x) memset(x,0,sizeof(x)) #define OFF(x) memset(x,-1,sizeof(x)) #define MEM(x,a) memset((x),(a),sizeof(x)) #define BUG cout << "I am here" << endl #define lookln(x) cout << #x << "=" << x << endl
#define SI(a) scanf("%d", &a) #define SII(a,b) scanf("%d%d", &a, &b) #define SIII(a,b,c) scanf("%d%d%d", &a, &b, &c) const int INF_INT=0x3f3f3f3f; const long long INF_LL=0x7f7f7f7f; const int MOD=1e9+7; const double eps=1e-10; const double pi=acos(-1); typedef long long ll; using namespace std; int q; ll logs[100]; map<ll, ll> sum; void init() { logs[0] = 1LL; for (int i = 1; i <= 62;i++) { logs[i] = logs[i - 1] * 2 + 1; } } int get(ll x) { if (x == 1) return 0; else { for (int i = 1; i <= 62; i++) { if (x >= logs[i - 1] + 1 && x <= logs[i]) return i; } } } void change(ll u, ll v, ll w) { int du = get(u), dv = get(v); if (du > dv) { swap(du, dv); swap(u, v); } // v big for (int i = dv; i > du; i--) { sum[v] += w; v /= 2; } if (u == v) return; while (u != v) { sum[u] += w; sum[v] += w; u /= 2; v /= 2; } } ll query(ll u, ll v) { ll ret = 0; int du = get(u), dv = get(v); if (du > dv) { swap(du, dv); swap(u, v); } for (int i = dv; i > du; i--) { ret += sum[v]; v /= 2; } if (u == v) return ret; while (u != v) { ret += sum[u]; ret += sum[v]; u /= 2, v /= 2; } return ret; } int main(int argc, char const *argv[]) { #ifdef LOCAL freopen("C:\\Users\\john\\Desktop\\in.txt","r",stdin); // freopen("C:\\Users\\john\\Desktop\\out.txt","w",stdout); #endif init(); SI(q); for (int i = 1; i <= q; i++) { int op; SI(op); if (op == 1) { ll u, v, w; scanf("%I64d%I64d%I64d", &u, &v, &w); change(u, v, w); } else if (op == 2) { ll u, v; scanf("%I64d%I64d", &u, &v); printf("%I64d\n", query(u, v)); } } return 0; }

相關推薦

Codeforces 696A Lorenzo Von Matterhorn(LCA)

題意: 給你一棵樹,其實就是按照線段樹的方法建的樹,有兩種操作,將u到v的路徑上的邊權全部加w,然後詢問從u到v的路徑上的邊權和。 解法: 因為節點的編號很大,所以不能直接建樹,但是可以知道,這棵樹的最大深度也就是62層,所以我們可以用map

C. Lorenzo Von Matterhorn LCA

nal always clear emp sla head positive type fir C. Lorenzo Von Matterhorn time limit per test 1 second memory limit per test 25

Codeforces Round 362 (Div 2)C】【STL-map 最近公共祖先思想】Lorenzo Von Matterhorn 數域二叉樹的路徑權值變更查詢

Barney lives in NYC. NYC has infinite number of intersections numbered with positive integers starting from 1. There exists a bidirectional road between

CF696A Lorenzo Von Matterhorn 二叉樹

Barney lives in NYC. NYC has infinite number of intersections numbered with positive integers starting from 1. There exists a bidirectional road betwe

CF696A Lorenzo Von Matterhorn

Barney lives in NYC. NYC has infinite number of intersections numbered with positive integers starting from 1. There exists a bidirectiona

YTU_3309: Lorenzo Von Matterhorn(完全二叉樹 最近公共祖先)

3309: Lorenzo Von Matterhorn 時間限制: 1 Sec  記憶體限制: 128 MB 提交: 6  解決: 6 [提交][狀態][討論版][命題人:acm4302] 題目描述 Barney住在紐約。紐約市有無限數量的路口,路口為從1開始編號的正

Codeforces-1062E:Company(LCA+線段樹)

E. Company time limit per test 2 seconds memory limit per test 256 megabytes inputstandard input outputstandard output The company

CodeForces】827 D. Best Edge Weight 最小生成樹+倍增LCA+並查集

樹邊 best edge blog ORC pos clas 無向連通圖 並查集 【題意】給定n個點m條邊的帶邊權無向連通圖,對每條邊求最大邊權,滿足其他邊權不變的前提下圖的任意最小生成樹都經過它。n,m<=2*10^5,1<=wi<=10^9。 【算法】

CodeForces - 932D. Tree(書上倍增+LCA

題目連結:http://codeforces.com/problemset/problem/932/D You are given a node of the tree with index 1 and with weight 0. Let cnt&nbs

LCA+最短路】Codeforces - 1051 - F. The Shortest Statement

題目連結<http://codeforces.com/problemset/problem/1051/F> 題意: 給出一張n個點,m條邊的無向連通圖。有q次詢問,每次詢問兩個節點的最短距離。 (1≤n,m≤1e5,m−n≤20,1≤q≤1e5) 

codeforces 1062E Company dfs序+線段樹+lca

E. Company 題意:給你一顆樹,有q次操作,每次操作詢問一個區間 l r,你可以刪除區間內任意一個節點,使得這個區間的lca最大,並輸出刪除的節點和區間lca。(每次操作獨立不影響下一次操作) 思路:我們可以先在樹上走一遍dfs序,每次詢問的區間,決定lca的肯定是dfs序最大和

2018.09.24 codeforces 1051F. The Shortest Statement(dijkstra+lca

傳送門 這真是一道一言難盡的題。 首先比賽的時候居然沒想出來正解。 其次賽後除錯一直調不出來最後發現是depth傳錯了。 其實這是一道簡單題啊。 對於樹邊直接lca求距離。 由於非樹邊最多21條。 因此

Codeforces】1051F. The Shortest Statement【MST+LCA+最短路】

F. The Shortest Statement 【題目描述】 傳送門 【題解】 題目也說了,重點是m-n<=20,我們就可以先跑最小生成樹,最後剩下最多21條邊,對著44個端點(包括起點和終點)用LCA建圖,跑最短路就可以了。 程式碼如下 #inclu

codeforces 1062E Company dfs序+線段樹+lca

題意:給你一顆樹,有q次操作,每次操作詢問一個區間 l r,你可以刪除區間內任意一個節點,使得這個區間的lca最大,並輸出刪除的節點和區間lca。(每次操作獨立不影響操作) 思路:我們可以先在樹上走一遍dfs序,每次詢問的區間,決定lca的肯定是dfs序最大和最小的兩個

codeforces 733 F. Drivers Dissatisfaction(最小生成樹+lca+倍增去環)

題目連結 F. Drivers Dissatisfaction time limit per test 4 seconds memory limit per test 256 megabytes input standard input output s

Codeforces Round #294 (Div. 2) E. A and B and Lecture Rooms(lca+思維,樹上尋找與給定兩個點距離相等的點的個數)

E. A and B and Lecture Rooms time limit per test 2 seconds memory limit per test 256 megabytes input standard input output

CodeForces 609 E.Minimum spanning tree for each edge(最小生成樹-Kruskal+線上倍增LCA

Description 給出一個n個點m條邊的無向連通圖,對於每一條邊,問包含該條邊的最小生成樹權值和 Input 第一行兩個整數n和m表示點數和邊數,之後m行每行三個整數u,v,w表示u和v之間有一條邊權為w的邊(1<=n<=2e5,n-1&

codeforces 733F LCA+最小生成樹

題意:給一個圖,及每條邊的邊權,然後每條邊都可以使自己的邊權減少1,但是需要費用ci,然後你有S的費用,問你如何分配這些費用使得最小生成樹的值最小 思路:首先要明確對於這所有的費用,我是全部用在一條邊上的,也就是說只用修改一條邊的權值,那麼我們可以先將原圖的最小生成樹找出

Educational Codeforces Round 51 (Rated for Div. 2) F. The Shortest Statement (最短路+LCA)

原題地址:http://codeforces.com/contest/1051/problem/F 題意:給你nnn個點,mmm條邊。m−n&lt;=20m-n&lt;=20m−n<=20。保證圖連通 問你任意兩點的最短距離是多少。 思路:

Codeforces 916E(思維+dfs序+線段樹+LCA)

題面 傳送門 題目大意:給定初始根節點為1的樹,有3種操作 1.把根節點更換為r 2.將包含u,v的節點的最小子樹(即lca(u,v)的子樹)所有節點的值+x 3.查詢v及其子樹的值之和 分析 看到批量修改子樹,我們想到將樹上操作轉化為區間操作