首页 > 代码库 > hdu3830(lca + 二分)
hdu3830(lca + 二分)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3830
题意: 有三个点 a, b, c, 对于其中任意一点 x 可以跨过一个点移动到另一个位置, 当且仅当移动前后的 x 与其所跨越的点的距离相等 .给出两组点, 问其能否相互到达, 若能并输出最少需要移动多少步 .
思路: http://www.cnblogs.com/scau20110726/archive/2013/06/14/3135024.html
代码:
1 #include <iostream> 2 #include <stdio.h> 3 #include <algorithm> 4 #define ll long long 5 using namespace std; 6 7 struct node{ 8 ll x, y, z, d; 9 }; 10 11 void f(node &s){ 12 ll cnt[3]; 13 cnt[0] = s.x; 14 cnt[1] = s.y; 15 cnt[2] = s.z; 16 sort(cnt, cnt + 3); 17 s.x = cnt[0]; 18 s.y = cnt[1]; 19 s.z = cnt[2]; 20 } 21 22 bool equal(node a, node b){//判断两个节点是否想等 23 if(a.x == b.x && a.y == b.y && a.z == b.z) return true; 24 return false; 25 } 26 27 node get_root(node &root){//这里要记录一下深度 28 ll r; 29 node cnt = root; 30 ll p = cnt.y - cnt.x; 31 ll q = cnt.z - cnt.y; 32 while(p != q){ 33 if(q > p){ //右边大于左边 34 r = (q - 1) / p; 35 cnt.x += r * p; 36 cnt.y += r * p; 37 }else{ 38 r = (p - 1) / q; 39 cnt.z -= r * q; 40 cnt.y -= r * q; 41 } 42 root.d += r; 43 f(cnt); //注意每个节点都要维护 44 p = cnt.y - cnt.x; 45 q = cnt.z - cnt.y; 46 } 47 return cnt; 48 } 49 50 node get_pre(node cnt, ll step){ //返回cnt向上移动step步后到达的位置 51 ll p, q, r; 52 while(step > 0){ 53 p = cnt.y - cnt.x; 54 q = cnt.z - cnt.y; 55 if(q > p){ 56 r = (q - 1) / p; 57 if(r > step) r = step;//注意剩余步数不足的情况 58 cnt.x += r * p; 59 cnt.y += r * p; 60 }else{ 61 r = (p - 1) / q; 62 if(r > step) r = step; 63 cnt.z -= r * q; 64 cnt.y -= r * q; 65 } 66 step -= r; 67 f(cnt); 68 } 69 return cnt; 70 } 71 72 ll solve(node s, node e){ 73 ll l = 0, r = s.d < e.d ? s.d : e.d; 74 ll cnt = r; 75 while(l <= r){ 76 ll mid = (l + r) >> 1; 77 ll gg = cnt - mid;// mid 为 lca 位置, gg 为移动步数 78 if(equal(get_pre(s, gg), get_pre(e, gg))) l = mid + 1; 79 else r = mid - 1; 80 } 81 return ((cnt - (l - 1)) << 1);// l - 1 为lca位置 82 } 83 84 int main(void){ 85 node s, e; 86 while(~scanf("%lld%lld%lld%lld%lld%lld", &s.x, &s.y, &s.z, &e.x, &e.y, &e.z)){ 87 s.d = e.d = 0; 88 f(s); 89 f(e); 90 if(!equal(get_root(s), get_root(e))){ //根节点不同无法到达 91 puts("NO"); 92 continue; 93 } 94 ll d = abs(s.d - e.d); 95 if(s.d > e.d) s = get_pre(s, d); //使两者处于同一深度 96 else e = get_pre(e, d); 97 int sol = solve(s, e); 98 puts("YES"); 99 printf("%lld\n", d + sol); 100 } 101 return 0; 102 }
hdu3830(lca + 二分)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。