Codeforces Round #362 (Div. 2) C. Lorenzo Von Matterhorn LCA(最近公共祖先)

C. 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 intersections i and 2i and
another road between i and 2i?+?1 for
every positive integer i. 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 will q consecutive events happen soon. There
are two types of events:

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

2. Barney starts moving from some intersection v and goes to intersection u 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 form 1 v u w if
it‘s an event when government makes a new rule about increasing the passing fee of all roads on the shortest path from u to v by w dollars,
or in form2 v u if
it‘s an event when Barnie goes to cuddle from the intersection v to the intersection u.

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:

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

Source

Codeforces Round #362 (Div. 2)

My Solution

LCA(最近公共祖先) 在有根树中,找出某两个结点u和v最近的公共祖先(或者说,离树根最远的公共祖先)。

类似于这样来访问

inline int LCA(const int &u, const int &v)

{

while (u != v){

if(u < v){ //if(v < u){

swap(u, v);

}

u = u/2;        // v/2 is parent of vertex v

}

return u;

}

每次修改的时候直接修改就行

1e18  -> 2^63次所以每次 2*63*q == 1e5

复杂度 O(2*63*n)

此外对于 map<pair<LL, LL>, LL> mpt;//map tree

和 map<LL, map<LL, LL> > mpt;//map tree

前面用 Codeforces上的数据做了测试, 这两种写法时间上是差不多的, 然而在空间复杂度上 前者是后者的一半

所以以后就用map<pair<LL, LL>, LL> mpt;//map tree 来处理 1<= u, v <= 1e18, w 这样节点标号很大的情况好了

如果时间压的比较紧可能可以尝试用

FF 计算机...  柱爷

离散化

vector<pair<int,int>> G[N]

读完后sort每个G[i]

后面二分找

#include <iostream>
#include <cstdio>
#include <map>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 8;

map<pair<LL, LL>, LL> mpt;//map tree

int main()
{
    #ifdef LOCAL
    freopen("a.txt", "r", stdin);
    //freopen("b.txt", "w", stdout);
    int T = 1;
    while(T--){
    #endif // LOCAL
    ios::sync_with_stdio(false);
    cin.tie(0);

    LL q, op, u, v, w, ans;
    cin>>q;
    while(q--){
        cin>>op>>u>>v;
        if(op == 1){
            cin>>w;
            while(u != v){
                if(u < v){
                    swap(u, v);
                }
                mpt[make_pair(u / 2, u)] += w;
                u /= 2;
            }
        }
        else{
            ans = 0;
            while(u != v){
                if(u < v){
                    swap(u, v);
                }
                ans += mpt[make_pair(u / 2, u)];
                u /= 2;
            }
            cout<<ans<<endl;
        }
    }

    #ifdef LOCAL
    printf("\n");
    }
    #endif // LOCAL
    return 0;
}

Thank you!

------from ProLights

时间: 2024-12-15 07:01:34

Codeforces Round #362 (Div. 2) C. Lorenzo Von Matterhorn LCA(最近公共祖先)的相关文章

Codeforces Round #362 (Div. 2) C. Lorenzo Von Matterhorn (类似LCA)

题目链接:http://codeforces.com/problemset/problem/697/D 给你一个有规则的二叉树,大概有1e18个点. 有两种操作:1操作是将u到v上的路径加上w,2操作是求u到v上的路径和. 我们可以看出任意一个点到1节点的边个数不会超过64(差不多就是log2(1e18)),所以可以找最近相同祖节点的方式写. 用一条边的一个唯一的端点作为边的编号(比如1到2,那2就为这条边的编号),由于数很大,所以用map来存. 进行1操作的时候就是暴力加w至u到LCA(u,v

Codeforces Round #362 (Div. 2) ABCDE

A. Pineapple Incident 题解: 水题...注意没有t+1这种情形 代码: #include<bits/stdc++.h> #define pb push_back #define mp make_pair #define se second #define fs first #define ll long long using namespace std; const int INF=1e9+10; const int maxn=1000000+5; ll read() {

Codeforces Round #629 (Div. 3) E. Tree Queries(lca题)

https://codeforces.com/contest/1328/problem/E E. Tree Queries You are given a rooted tree consisting of nn vertices numbered from 11 to nn. The root of the tree is a vertex number 11. A tree is a connected undirected graph with n−1n−1 edges. You are

Codeforces Round #362 (Div. 1) B. Puzzles 树形dp,概率

题目链接: http://codeforces.com/problemset/problem/696/B 题意: 一个树,dfs遍历子树的顺序是随机的.所对应的子树的dfs序也会不同.输出每个节点的dfs序的期望 思路: http://www.cnblogs.com/01world/p/5795498.html 假设四个子节点为A,B,C,D,因为排列等可能,所以A在B前面的概率跟A在B后面的概率相等,C和D对于A而言一样.所以遍历A的时间期望就是( t(B) + t(C) + t(D) )/2

【转载】【树形DP】【数学期望】Codeforces Round #362 (Div. 2) D.Puzzles

期望计算的套路: 1.定义:算出所有测试值的和,除以测试次数. 2.定义:算出所有值出现的概率与其乘积之和. 3.用前一步的期望,加上两者的期望距离,递推出来. 题意: 一个树,dfs遍历子树的顺序是随机的.所对应的子树的dfs序也会不同.输出每个节点的dfs序的期望   思路: 分析一颗子树: 当前已知节点1的期望为1.0 ->anw[1]=1.0 需要通过节点1递推出节点2.4.5的期望值 1的儿子分别是2.4.5,那么dfs序所有可能的排列是6种: 1:1-2-4-5  (2.4.5节点的

D. Puzzles(Codeforces Round #362 (Div. 2))

D. Puzzles Barney lives in country USC (United States of Charzeh). USC has n cities numbered from 1 through n and n - 1 roads between them. Cities and roads of USC form a rooted tree (Barney's not sure why it is rooted). Root of the tree is the city

Codeforces Round #629 (Div. 3) E. Tree Queries(LCA)

https://codeforces.com/contest/1328/problem/E 题目所描述的是一棵树,题中已明示1为root结点. 题目可以转化为,是否存在一条路径,满足集合中的k个点到路径的距离小于等于1? 思路: 1.首先倍增离线预处理出结点深度,便于后续在线询问LCA 2.对于每次的询问,依次扫描k个点.对于集合中的u和v两点,每次我们求出u和v的LCA,计算u和v到LCA的距离,如果u和v到LCA的距离同时大于1,那么说明无法找到一条路径,使得u和v到该路径链的距离小于等于1

Codeforces Round #545 (Div. 2)D(KMP,最长公共前后缀,贪心)

#include<bits/stdc++.h>using namespace std;const int N=1000007;char s1[N],s2[N];int len1,len2;int nex[N];int cnt1[7],cnt2[7];int main(){    scanf("%s %s",s1+1,s2+1);    len1=strlen(s1+1);    len2=strlen(s2+1);    for(int i=1;i<=len1;i++

Codeforces Round #279 (Div. 2) ABCD

Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name     A Team Olympiad standard input/output 1 s, 256 MB  x2377 B Queue standard input/output 2 s, 256 MB  x1250 C Hacking Cypher standard input/output 1 s, 256 MB  x740 D Chocolate standard input/