Codeforces 697C题解报告

Codeforces 697C
题目链接:http://codeforces.com/problemset/problem/697/C

题意:给了一棵二叉树,二叉树每个结点的编号与同层数的满二叉树相同,注意树的结点范围是1e18,需要用到long long以及map。询问中有两种操作。第一种,给定结点u,v以及一个权值w,从u到v的最短路径上所有的结点都加上这个权值;第二种,给定结点u,v,查询u到v的最短路径上的所有结点的权值和。

分析:由于是二叉树的结点编号与同层数的满二叉树相同,对于每个结点,从给定的结点位置开始,将结点位置整除二就能得到最短路径上下一个点的位置,直到两个结点相遇为止,一直对途经的结点进行加权/求和操作即可。可以说是最基础的lca思想吧。

#include <algorithm> //swap
#include <iostream>
#include <cstring>
#include <map>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 200010;
int i, j, k;
int m, n;
//  u/v 1e18
map<ll, ll>mp;
int main() {
	scanf("%d", &n);
	mp.clear();
	for (i = 0; i < n; i++) {
		int ch;
		scanf("%d", &ch);
		ll u, v, w;
		if (ch == 1) {
			scanf("%lld%lld%lld", &u, &v, &w);
			while (u != v) {
				if (u < v) {
					mp[v] += w;
					v /= 2;
				}
				else {
					mp[u] += w;
					u /= 2;
				}
			}
		}
		else {
			scanf("%lld%lld", &u, &v);
			ll res = 0;
			while (u != v) {
				if (u < v) {
					res += mp[v];
					v /= 2;
				}
				else {
					res += mp[u];
					u /= 2;
				}
			}
			printf("%lld\n", res);
		}
	}
	return 0;
}
发布了4 篇原创文章 · 获赞 0 · 访问量 457

猜你喜欢

转载自blog.csdn.net/qq_43470416/article/details/104009955