zoukankan      html  css  js  c++  java
  • 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
    ", d + sol);
    100     }
    101     return 0;
    102 }
    View Code
  • 相关阅读:
    Security headers quick reference Learn more about headers that can keep your site safe and quickly look up the most important details.
    Missing dollar riddle
    Where Did the Other Dollar Go, Jeff?
    proteus 与 keil 联调
    cisco router nat
    router dhcp and dns listen
    配置802.1x在交换机的端口验证设置
    ASAv931安装&初始化及ASDM管理
    S5700与Cisco ACS做802.1x认证
    playwright
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/7282559.html
Copyright © 2011-2022 走看看