qwq

这题一看就不会,如果不是gg让做我是坚决不会做的

画图模拟,因为一次只能跳过一个棋子,所以对于一种情况只有三种移动方式:

  1. 中间向左跳
  2. 中间向右跳
  3. 左或右(距中间近的那个)向中间跳

发现,除了跳到边界,当左右到中间的距离相等的时候就不能再向中间跳了,

而任意一种情况只要一直重复方式3就能达到这样的平衡状态,也就是说这个状态可以通过方式1、2的组合达到这种情况所有的其他状态。

把这样的平衡状态当作这种情况的父亲(根节点)。

那么,首先判断两种情况的根节点是否相同,

如果相同,说明两种情况在向根节点转移的过程中可能会出现相等的情况。

最坏的情况,就是一种情况先转移到根节点,再转移到另一种情况。

如果把转移的过程看做一个树形结构,从某个点向左、右跳是左、右儿子,向中间跳(只有一种可能)是父亲,

那么从两种情况同时向上找,就类似于一个求lca的过程!

不过这棵树的左右儿子都是无限的,没法求出所有情况,所以不需要真的求出一棵树。

只要模拟在树上求LCA的过程即可。

记录左右两点到中间的距离x,y,若x<y,则左边向中间跳,即左坐标+2x,等同于左、中两点的坐标都+x,

反之则右、中两点的坐标都-y。

转移的过程中记录转移的步数可以得到深度。

首先在找根结点的时候可以得到两种情况到根结点的深度dA,dB,

然后仿照LCA的过程,把较深的一个向上走|dA-dB|步。

这时问题来了,既然没有完整的树,也就没法通过倍增的方法向上跳。

那么就只能一步一步的试了,如果向上一步后两种情况的坐标不同就两步.....

二分答案枚举步数可以优化这个过程,如果跳mid步后相同,就r=mid,否则l=mid+1。可以看出这个过程和倍增求LCA也是很相似的。

最后答案即为两个同步跳的+深的节点自己跳的=ans*2+|dA-dB|。

但是考虑这样一种情况:左、中两点非常近,但右点非常远。这时候左中两点来回相互跳要重复很多次,

这个y-x-x-x-…一直减到x≥y为止的过程,可以化简为y-kx。

k=(y-1)/x。为什么呢?当y=x的时候,其实是不能跳的。

随便带几个数试试:

坐标为1,3,9,x=2,y=6,跳(6-1)/2=2次,坐标则为5,7,9;

坐标为1,3,10,x=2,y=7,跳(7-1)/2=3次,坐标则为7,9,10,然后再跳右边的...

不过这时要注意,如果kx>规定要跳的次数res,那么跳的次数就应该是res而不是kx。

代码如下

#include<cstdio>
#include<iostream>
#include<algorithm>
#define MogeKo qwq
using namespace std;
const int INF = 2e9+;
int dA,dB,dd,ans; struct node {
int a,b,c;
bool operator == (const node &N) const {
return a==N.a && b==N.b && c==N.c;
}
void input() {
int p[];
for(int i = ; i <= ; i++)
scanf("%d",&p[i]);
sort(p+,p+);
a = p[],b = p[],c = p[];
}
} A,B; node getfa(node t,int res,int &dpth) {
int cnt;
dpth = ;
while(res) {
int x = t.b-t.a;
int y = t.c-t.b;
if(x == y) return t;
if(x < y) {
cnt = min((y-)/x,res);
t.a += cnt*x;
t.b += cnt*x;
} else {
cnt = min((x-)/y,res);
t.b -= cnt*y;
t.c -= cnt*y;
}
res -= cnt;
dpth += cnt;
}
return t;
} int main() {
A.input(),B.input();
if(getfa(A,INF,dA) == getfa(B,INF,dB))
printf("YES\n");
else {
printf("NO\n");
return ;
}
if(dA < dB) {
swap(A,B);
swap(dA,dB);
}
A = getfa(A,dA-dB,dd);
int l = ,r = INF;
while(l < r) {
int mid = (l+r)>>;
if(getfa(A,mid,dd)==getfa(B,mid,dd)) {
ans = mid;
r = mid;
} else l = mid+; }
printf("%d",ans*+dA-dB);
return ;
}

Luogu P1852 BZOJ 2144 [国家集训队]跳跳棋的更多相关文章

  1. 洛谷 P1852 [国家集训队]跳跳棋 解题报告

    P1852 [国家集训队]跳跳棋 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在\(a\),\(b\), ...

  2. P1852 [国家集训队]跳跳棋

    P1852 [国家集训队]跳跳棋 lca+二分 详细解析见题解 对于每组跳棋,我们可以用一个三元组(x,y,z)表示 我们发现,这个三元组的转移具有唯一性,收束性 也就是说,把每个三元组当成点,以转移 ...

  3. 【洛谷】1852:[国家集训队]跳跳棋【LCA】【倍增?】

    P1852 [国家集训队]跳跳棋 题目背景 原<奇怪的字符串>请前往 P2543 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个 ...

  4. 洛谷 P1852 [国家集训队] 跳跳棋

    题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...

  5. [BZOJ2144]国家集训队 跳跳棋

    题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...

  6. luogu P1852 [国家集训队]跳跳棋

    luogu 直接操作是不可能的,考虑发现一些性质.可以发现如果每次跳的棋子都是两边的,那么最多只有一种方案,那么就把这样操作得到的状态记为当前状态的父亲,从一个状态这样做一定会结束.那么如果两个状态只 ...

  7. BZOJ.2653.[国家集训队]middle(可持久化线段树 二分)

    BZOJ 洛谷 求中位数除了\(sort\)还有什么方法?二分一个数\(x\),把\(<x\)的数全设成\(-1\),\(\geq x\)的数设成\(1\),判断序列和是否非负. 对于询问\(( ...

  8. BZOJ.2565.[国家集训队]最长双回文串(Manacher/回文树)

    BZOJ 洛谷 求给定串的最长双回文串. \(n\leq10^5\). Manacher: 记\(R_i\)表示以\(i\)位置为结尾的最长回文串长度,\(L_i\)表示以\(i\)开头的最长回文串长 ...

  9. BZOJ 2631 [国家集训队]Tree II (LCT)

    题目大意:给你一棵树,让你维护一个数据结构,支持 边的断,连 树链上所有点点权加上某个值 树链上所有点点权乘上某个值 求树链所有点点权和 (辣鸡bzoj又是土豪题,洛谷P1501传送门) LCT裸题, ...

随机推荐

  1. 探索Windows命令行系列(1):导航目录

    探索Windows命令行系列(1):导航目录 探索Windows命令行系列(2):命令行工具入门 探索Windows命令行系列(3):命令行脚本基础 探索Windows命令行系列(4):通过命令操作文 ...

  2. mpvue微信小程序多列选择器用法:实现省份城市选择

    前言 微信小程序默认给我们提供了一个省市区的picker选择器,只需将mode设置为region即可 <picker mode="region" bindchange=&qu ...

  3. 一键解决 go get golang.org/x 包失败

    问题描述 当我们使用 go get.go install.go mod 等命令时,会自动下载相应的包或依赖包.但由于众所周知的原因,类似于 golang.org/x/... 的包会出现下载失败的情况. ...

  4. ajax跨域请求,亲测有效

    跨域请求域有两种常用解决方案,jsonp和cors, 因为jsonp只能解决get请求问题,我这里用的是cors方法. js前端ajax请求: $.ajax({ url: "http://1 ...

  5. webpack4.0各个击破(3)—— Assets篇

    目录 一. Assets资源的基本处理需求 二. webpack处理引用资源 2.1 资源打标 2.2 引用优化 2.3 sprites雪碧图合成 2.4 图片压缩及其他 webpack作为前端最火的 ...

  6. [转]GitLab-CI与GitLab-Runner

    本文转自:https://www.jianshu.com/p/2b43151fb92e 一.持续集成(Continuous Integration) 要了解GitLab-CI与GitLab Runne ...

  7. WPF 窗口大小自适应

    在设置桌面不同分辨率以及较大DPI下,窗口如何显示的问题. 方案一 设置窗口最大值和最小值显示 通过对比当前屏幕的可显示区域,将窗口高宽最大值和最小值,设置为窗口的实际高宽(此例中仅设置高度) 界面设 ...

  8. WPF 中 DispatcherTimer 计时器

    在 WPF 中涉及到界面操作的计时器时,一定要使用 DispatcherTime,DispatcherTimer是为 WPF 专门设计的,不然的话会提示界面资源被其他线程所拥有而无法更新界面.Disp ...

  9. QT 自定义模态对话框

    新建一个MsgBox类 msgbox.h 代码 #ifndef MSGBOX_H #define MSGBOX_H #include <QDialog> #include <QPus ...

  10. Laravel5.5 邮件驱动使用 SMTP 驱动实现邮件发送

    laravel5.5 邮件驱动 Laravel 支持多种邮件驱动,包括 smtp.Mailgun.Maildrill.Amazon SES.mail 和 sendmail.Mailgun . Mail ...