CodeForces 697C Lorenzo Von Matterhorn
2016-08-09 22:23
302 查看
题意:有q个节点构成二叉树,有两种输入,第一种是1 v u w,代表是从v节点走到u节点需要w元。第二种是2 v u,代表是从v节点走到u节点,并且输出所需的钱。
思路:看到这道题的时候发现1 ≤ v, u ≤ 1018,这两个数特别大,感觉会用到map去存。另一个难点就是怎么去判断v节点和u节点是否在1的两侧或同侧。判断方法就是,先比较v,u两个点的大小,再将大的那个节点除以二(就一定是它的父亲节点),直到比另一个点小,就开始将另一个点除以二,以此类推,如果除以若干个2之后这两个点相等,就意味着他俩是在1的同侧,反之异侧。具体看代码。
思路:看到这道题的时候发现1 ≤ v, u ≤ 1018,这两个数特别大,感觉会用到map去存。另一个难点就是怎么去判断v节点和u节点是否在1的两侧或同侧。判断方法就是,先比较v,u两个点的大小,再将大的那个节点除以二(就一定是它的父亲节点),直到比另一个点小,就开始将另一个点除以二,以此类推,如果除以若干个2之后这两个点相等,就意味着他俩是在1的同侧,反之异侧。具体看代码。
#include<cstdio> #include<map> using namespace std; map<long long, long long>M; int main() { int q; while(~scanf("%d", &q)) { int n; long long u, v ,w; for(int i = 0; i < q; i++) { scanf("%d", &n); 4000 if(n == 1) { scanf("%lld%lld%lld", &u, &v, &w); while(u != v) { while(u > v) { M[u] += w; u /= 2; } while(u < v) { M[v] += w; v /= 2; } } } if(n == 2) { long long sum = 0; scanf("%lld%lld", &u, &v); while(u != v) { while(u > v) { sum += M[u]; u /= 2; } while(u < v) { sum += M[v]; v /= 2; } } printf("%lld\n", sum); } } return 0; } }</span>
相关文章推荐
- Codeforces 25D. Roads not only in Berland 并查集
- codeforces 301 E. Infinite Inversions
- CodeForces 652C Foe Pairs
- Codeforces 711C Coloring Trees
- Codeforces 355C Vasya and Robot 暴力枚举
- CodeForces - 848A From Y to Y(构造)
- CodeForces - 586B
- Codeforces 217A. Ice Skating 搜索
- codeforces 416C C. Booking System
- CodeForces 645C Enduring Exodus
- CodeForces 617B 2
- CodeForces 176A Trading Business 贪心
- CodeForces - 849B Tell Your World(简单题)
- CodeForces - 609E(最下生成树+lca)
- CodeForces #174.div2.problem C
- Codeforces 450 C. Jzzhu and Chocolate
- CodeForces 546B
- CodeForces 140C - New Year Snowmen STL
- CodeForces 791B Bear and Friendship Condition【并查集】
- Codeforces 851D - Arpa and a list of numbers 【素数+前缀和】