洛谷P1852:跳跳棋(LCA,树形结构)
解析
考虑一个三元组(x,y,z)(x,y,z)(x,y,z),看它能如何跳
要么是yyy往左右跳,左右边界会变大
要么是两边往中间跳,由于最多跨过一个棋子,所以左右边界会变小
当三点等距时,无法往中间跳
于是我们惊喜的发现:可以互相转移的状态形成了一个二叉树形结构!!!
往中间跳的时候,相当于跳父亲;往两边跳相当于跳儿子
当且仅当两个状态的根相同时,有解
又由于这个跳的操作是可逆的,所以我们的问题就可以转化为两个点在树上的距离
于是我们就可以用类似倍增求LCA的思路解决本题
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e6+100;
const double eps=1e-6;
const int mod=1333331;
inline ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return f*x;
}int n,m,p;
struct node{ll a,b,c;inline void solve(){if(b>c) swap(b,c);if(a>b) swap(a,b);if(b>c) swap(b,c);return;}bool operator == (const node u)const{return a==u.a&&b==u.b&&c==u.c;}bool operator != (const node u)const{return a!=u.a||b!=u.b||c!=u.c;}
}u,v;
node walk(node o,ll lft){if(lft==0) return o;ll d1=o.b-o.a,d2=o.c-o.b;if(d1==d2) return o;if(d1<d2){int k=min((d2-1)/d1,lft);o.a+=k*d1,o.b+=k*d1;return walk(o,lft-k);}else{int k=min((d1-1)/d2,lft);o.b-=k*d2;o.c-=k*d2;return walk(o,lft-k);}
}
int dep(node o){int st=0,ed=2e9;while(st<ed){int mid=(st+ed)>>1;if(walk(o,mid+1)==walk(o,mid)) ed=mid;else st=mid+1;}return st;
}
void print(node o){printf("(%lld %lld %lld)\n",o.a,o.b,o.c);return;
}
int main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifu=(node){read(),read(),read()};v=(node){read(),read(),read()};u.solve(),v.solve();if(walk(u,2e9)!=walk(v,2e9)) printf("NO\n");else{printf("YES\n");int aa=dep(u),bb=dep(v);if(aa<bb) swap(u,v);int num=abs(aa-bb);int ans=num;for(int k=30;k>=0;k--){if(num>=(1<<k)) u=walk(u,1<<k),num-=(1<<k);}if(u==v){printf("%d\n",ans);return 0;}//printf("-- ans=%d\n",ans);//print(u);print(v);for(int k=30;k>=0;k--){node uu=walk(u,1<<k),vv=walk(v,1<<k);if(uu==vv) continue;u=uu;v=vv;ans+=(1<<(k+1));}printf("%d\n",ans+2);}return 0;
}
/*4a1 22 31 33 4
*/
洛谷P1852:跳跳棋(LCA,树形结构)相关推荐
- P1497[洛谷]P1852跳跳棋
P1497[洛谷]P1852跳跳棋 标签(空格分隔): 信息 图论 二分 洛谷 考题,看到就觉得是不可能写出来的那种,于是打了个bfs直接走人. 考完之后听吕大佬讲过之后觉得此题可谓绝妙啊%%% 屁颠 ...
- P1852 跳跳棋(建模LCA)
P1852 跳跳棋(建模&LCA) 往外跳有个两个状态,往里跳只能有一个唯一父亲状态. 所以是一个二叉树. 将给定的起始和目标状态 向上找到根,判断是否相等.不相等无解. 否则类似求LCA的思 ...
- 跳跳棋(国家集训队,LCA,洛谷P1852,BZOJ[2144])
文章目录 题目 思路 代码 题目 题目链接 描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的游戏:棋盘上有333颗棋子,分别在a,b,ca,b ...
- 洛谷 P1852 [国家集训队] 跳跳棋
题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...
- 洛谷-P4995-跳跳
跳跳! - 洛谷 解题思路: 1.由题意得,要求所耗费的体力最大值,体力值的计算 公式给出,可以判断,两个石头的高度差越大即越 好,所以这里的贪心思想是总要跳到和当前石头高度 差最大的那个石头 2. ...
- BZOJ2144跳跳棋——LCA+二分
题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子.我们用跳跳棋来做一个简单的 游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...
- 洛谷P1852 奇怪的字符串
题目描述 输入两个01串,输出它们的最长公共子序列的长度 输入输出格式 输入格式: 一行,两个01串 输出格式: 最长公共子序列的长度 输入输出样例 输入样例#1: 复制 01010101010 00 ...
- 洛谷【入门3】循环结构
P1980 [NOIP2013 普及组]计数问题 题目链接:[NOIP2013 普及组] 计数问题 - 洛谷 题目:试计算在区间 1 到 n 的所有整数中,数字 x(0≤x≤9)共出现了多少次?例如 ...
- 洛谷——【入门2】分支结构
文章目录 题单简介 [深基1-2]小学数学 N 合一 题目描述 问题 1 问题 2 问题 3 问题 4 问题 5 问题 6 问题 7 问题 8 问题 9 问题 10 问题 11 问题 12 问题 13 ...
最新文章
- 怎么在安卓布局里设置滚动字体_Get新技能|如何在手机上设置文字版拼音?
- WEB安全基础-XSS基础
- airtest测试用例_Airtest 常用方法
- Java Switch语句及性能剖析(转载补充)
- JSK-T1011 反向输出一个三位数【入门】
- SQL 基础教程 练习题 Chapter 1
- 全球区块链专利排行榜中国52家企业上榜
- Excel快速合并,简单方法,轻松搞定!
- proxifier中文汉化版
- Structure SLAM 相关论文阅读(一):消影点/消失点/灭点检测提取
- springboot no tests were found
- 暴走英雄坛服务器维护到什么时候,暴走英雄坛在4月25日更新了什么 最新维护内容介绍...
- 自己用C语言写RL78 serial bootloader
- 21岁女总裁董思阳,她做对了那些事情
- 第4章第15节:图表:使用饼图制作投资公司四季收益图表 [PowerPoint精美幻灯片实战教程]
- 5. Layui数据表格的快速使用
- 进入JavaScript
- Day28-Linux入门01
- 操作系统 考研复试/面试指南
- Jmeter+InfluxDB+Grafana+Prometheus搭建遇过的问题
热门文章
- 这本造价500万的“黑科技”日历,用377张爆美插画给你365天理想生活
- 有哪些命令行的软件堪称神器?
- 项目管理 计算机仿真,分析计算机仿真技术在工程项目施工管理中的运用.pdf
- textjoin去重_SuperJoinText这个函数,弥补了TEXTJOIN的缺憾
- html试题及答案,HTML试题及答案
- 华为交换机linux版本号,Cisco和华为交换机常用配置命令总结
- python类变量共享吗_第7.12节 可共享的Python类变量
- cas 4.2.7 官方手册_海城市地区,保险手册核验的简单流程
- python连接mongodb数据库_python连接mongodb操作数据示例(mongodb数据库配置类)
- 7-52 两个有序链表序列的交集 (20 分)(思路加详解尾插法)come Boby!