题目

分析

首先对于一个状态(a,b,c),假定a<=b<=c;

现在考虑一下这个状态,的转移方案:

\[1,中间向两边跳(a,b,c)-->(a*2-b,a,c)、(a,b,c)-->(a,c,2*c-b)
\]

\[2、两边向中间跳\left\{\begin{array}\\b-a>c-b,(a,b,c)-->(a,2*b-c,b) \\b-a<c-b,(a,b,c)-->(b,2*b-a,c) \end{array}\right.
\]

我们将一个状态两边向中间转移后的状态设为这个状态的父亲,我们发现,这刚好形成了一颗树。

那么从起点和终点都分别向父亲跳,用hash判重,如果有交点就输出yes以及ans,反之。

但这显然会超时。

我们用二元组(l,r)来代表每一个状态,l=b-a,r=c-b。(显然根节点就是l=r的二元组)

当这个状态向父亲跳时,就变成

\[\left\{\begin{array}\\l>r,(l,r)-->(l-r,r) \\l<r,(l,r)-->(l,r-l) \end{array}\right.
\]

发现这样转移就类似于辗转相除法!

用倍增求lca就可以了。

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const long long maxlongint=2147483647;
const long long mo=10000007;
const long long N=50005;
using namespace std;
long long b[4],n=3,m,t[4],a[4],mi[35],deep,deep1,a1[4],b1[4],f[2][2],dd,l,r,ll,rr,ans;
bool q;
long long do1(long long x)
{
long long k=0,p;
while(x>0)
{
sort(a+1,a+3+1);
k=0;
if(l==r)
{
q=false;
break;
}
if(l>r)
{
if(l%r==0) k--;
k+=l/r;
p=r;
if(x-k>=0)
{
l-=k*r;
x-=k;
a[3]-=(k-k/2)*p*2;
a[2]-=(k/2)*p*2;
}
else
{
l-=x*r;
k=x;
a[3]-=(k-k/2)*p*2;
a[2]-=(k/2)*p*2;
break;
}
}
else
{
if(r%l==0) k--;
k+=r/l;
p=l;
if(x-k>=0)
{
r-=k*l;
x-=k;
a[1]+=(k-k/2)*p*2;
a[2]+=(k/2)*p*2;
}
else
{
r-=x*l;
k=x;
a[1]+=(k-k/2)*p*2;
a[2]+=(k/2)*p*2;
break;
}
}
}
}
long long do2(long long x)
{
long long k=0,p;
while(x>0)
{
sort(b+1,b+3+1);
k=0;
if(ll==rr)
{
q=false;
break;
}
if(ll>rr)
{
if(ll%rr==0) k--;
k+=ll/rr;
p=rr;
if(x-k>=0)
{
ll-=k*rr;
x-=k;
b[3]-=(k-k/2)*p*2;
b[2]-=(k/2)*p*2;
}
else
{
ll-=x*rr;
k=x;
b[3]-=(k-k/2)*p*2;
b[2]-=(k/2)*p*2;
break;
}
}
else
{
if(rr%ll==0) k--;
k+=rr/ll;
p=ll;
if(x-k>=0)
{
rr-=k*ll;
x-=k;
b[1]+=(k-k/2)*p*2;
b[2]+=(k/2)*p*2;
}
else
{
rr-=x*ll;
k=x;
b[1]+=(k-k/2)*p*2;
b[2]+=(k/2)*p*2;
break;
}
}
}
}
int main()
{
for(long long i=1;i<=n;i++) scanf("%lld",&a[i]);
for(long long i=1;i<=n;i++) scanf("%lld",&b[i]);
mi[0]=1;
for(long long i=1;i<=33;i++)
mi[i]=mi[i-1]*2;
sort(a+1,a+3+1);
sort(b+1,b+3+1);
f[0][0]=a1[0]=a[2]-a[1];
f[0][1]=a1[1]=a[3]-a[2];
f[1][0]=b1[0]=b[2]-b[1];
f[1][1]=b1[1]=b[3]-b[2];
deep=1;
deep1=1;
while(a1[0]!=a1[1])
{
long long k=0,p;
if(a1[0]>a1[1])
{
p=a1[1];
if(!(a1[0]%a1[1]))
{
k=a1[0]/a1[1]-1;
deep+=k;
a1[0]-=k*a1[1];
}
else
{
k=a1[0]/a1[1];
deep+=k;
a1[0]%=a1[1];
}
}
else
{
p=a1[0];
if(!(a1[1]%a1[0]))
{
k=a1[1]/a1[0]-1;
deep+=k;
a1[1]-=k*a1[0];
}
else
{
k=a1[1]/a1[0];
deep+=k;
a1[1]%=a1[0];
}
}
}
while(b1[0]!=b1[1])
{
long long k=0,p;
if(b1[0]>b1[1])
{
p=b1[1];
if(!(b1[0]%b1[1]))
{
k=b1[0]/b1[1]-1;
deep1+=k;
b1[0]-=k*b1[1];
}
else
{
k=b1[0]/b1[1];
deep1+=k;
b1[0]%=b1[1];
}
}
else
{
p=b1[0];
if(!(b1[1]%b1[0]))
{
k=b1[1]/b1[0]-1;
deep1+=k;
b1[1]-=k*b1[0];
}
else
{
k=b1[1]/b1[0];
deep1+=k;
b1[1]%=b1[0];
}
}
}
sort(a+1,a+3+1);
sort(b+1,b+3+1);
if(deep>deep1)
{
deep=deep^deep1;
deep1=deep^deep1;
deep=deep^deep1;
f[0][0]=f[0][0]^f[1][0];
f[1][0]=f[0][0]^f[1][0];
f[0][0]=f[0][0]^f[1][0];
f[0][1]=f[0][1]^f[1][1];
f[1][1]=f[0][1]^f[1][1];
f[0][1]=f[0][1]^f[1][1];
a[1]=a[1]^b[1];
b[1]=a[1]^b[1];
a[1]=a[1]^b[1];
a[2]=a[2]^b[2];
b[2]=a[2]^b[2];
a[2]=a[2]^b[2];
a[3]=a[3]^b[3];
b[3]=a[3]^b[3];
a[3]=a[3]^b[3];
}
ans=deep1-deep;
while(deep<deep1)
{
long long k=0;
if(f[1][0]>f[1][1])
{
if(f[1][0]%f[1][1]==0) k--;
k+=f[1][0]/f[1][1];
long long p=f[1][1];
if(deep1-k>=deep)
{
f[1][0]-=k*f[1][1];
deep1-=k;
b[3]-=(k-k/2)*p*2;
b[2]-=(k/2)*p*2;
}
else
{
f[1][0]-=(deep1-deep)*f[1][1];
k=deep1-deep;
b[3]-=(k-k/2)*p*2;
b[2]-=(k/2)*p*2;
break;
}
}
else
{
if(f[1][1]%f[1][0]==0) k--;
k+=f[1][1]/f[1][0];
long long p=f[1][0];
if(deep1-k>=deep)
{
f[1][1]-=k*f[1][0];
b[1]+=(k-k/2)*p*2;
b[2]+=(k/2)*p*2;
deep1-=k;
}
else
{
f[1][1]-=(deep1-deep)*f[1][0];
k=deep1-deep;
b[1]+=(k-k/2)*p*2;
b[2]+=(k/2)*p*2;
break;
}
}
}
deep1=deep;
dd=deep;
sort(a+1,a+3+1);
sort(b+1,b+3+1);
for(long long i=33;i>=0;i--)
{
if(mi[i]<=dd)
{
q=true;
l=f[0][0];
r=f[0][1];
for(long long j=1;j<=n;j++) a1[j]=a[j];
do1(mi[i]);
if(q)
{
ll=f[1][0];
rr=f[1][1];
for(long long j=1;j<=n;j++) b1[j]=b[j];
do2(mi[i]);
if(q)
{
sort(a+1,a+3+1);
sort(b+1,b+3+1);
if(a[1]==b[1] && a[2]==b[2] && a[3]==b[3])
{
for(long long j=1;j<=n;j++) a[j]=a1[j];
for(long long j=1;j<=n;j++) b[j]=b1[j];
continue;
}
f[0][0]=a[2]-a[1];
f[0][1]=a[3]-a[2];
f[1][0]=b[2]-b[1];
f[1][1]=b[3]-b[2];
ans+=mi[i]*2;
}
else
{
for(long long j=1;j<=n;j++) a[j]=a1[j];
for(long long j=1;j<=n;j++) b[j]=b1[j];
}
}
else
{
for(long long j=1;j<=n;j++) a[j]=a1[j];
}
}
}
if(a[1]==b[1] && a[2]==b[2] && a[3]==b[3])
{
printf("YES\n%lld",ans);
return 0;
}
l=f[0][0];
r=f[0][1];
do1(1);
ll=f[1][0];
rr=f[1][1];
do2(1);
sort(a+1,a+3+1);
sort(b+1,b+3+1);
ans+=2;
if(a[1]==b[1] && a[2]==b[2] && a[3]==b[3]) printf("YES\n%lld",ans);
else printf("NO");
}

【NOIP2016提高A组模拟8.15】Throw的更多相关文章

  1. NOIP2016提高A组模拟10.15总结

    第一题,就是将原有的式子一步步简化,不过有点麻烦,搞了很久. 第二题,枚举上下边界,维护一个单调队列,二分. 比赛上没有想到,只打了个暴力,坑了80分. 第三题,贪心,最后的十多分钟才想到,没有打出来 ...

  2. 【NOIP2016提高A组模拟10.15】打膈膜

    题目 分析 贪心, 先将怪物按生命值从小到大排序(显然按这个顺序打是最优的) 枚举可以发对少次群体攻击, 首先将所有的群体攻击发出去, 然后一个一个怪物打,当当前怪物生命值大于2,如果还有魔法值就放重 ...

  3. 【NOIP2016提高A组模拟10.15】最大化

    题目 分析 枚举两个纵坐标i.j,接着表示枚举区域的上下边界, 设对于每个横坐标区域的前缀和和为\(s_l\),枚举k, 显然当\(s_k>s_l\)时,以(i,k)为左上角,(j,k)为右下角 ...

  4. 【NOIP2016提高A组模拟10.15】算循环

    题目 分析 一步步删掉循环, 首先,原式是\[\sum_{i=1}^n\sum_{j=1}^m\sum_{k=i}^n\sum_{l=j}^m\sum_{p=i}^k\sum_{q=j}^l1\] 删 ...

  5. 【NOIP2016提高A组模拟9.15】Map

    题目 分析 发现,当原图是一棵树的时候,那么新建一条边后,就会变成环套树, 而环内的所有点对都是安全点对,如果环中有k个点,答案就是\(k(k-1)\) 联想到,当把原图做一遍tarjan缩点,每个环 ...

  6. 【NOIP2016提高A组模拟9.15】Osu

    题目 分析 考虑二分答案, 二分小数显然是不可取的,那么我们将所有可能的答案求出来,记录在一个数组上,排个序(C++调用函数很容易超时,手打快排,时间复杂度约为\(O(>8*10^7)\),但相 ...

  7. 【NOIP2016提高A组模拟9.15】Math

    题目 分析 因为\((-1)^2=1\), 所以我们只用看\(\sum_{j=1}^md(i·j)\)的值模2的值就可以了. 易证,一个数x,只有当x是完全平方数时,d(x)才为奇数,否则为偶数. 那 ...

  8. 【NOIP2016提高A组模拟8.15】Garden

    题目 分析 其实原题就是[cqoi2012][bzoj2669]局部极小值. 有一个n行m列的整数矩阵,其中1到nm之间的每个整数恰好出现一次.如果一个格子比所有相邻格子(相邻是指有公共边或公共顶点) ...

  9. 【NOIP2016提高A组模拟8.15】Password

    题目 分析 首先我们知道,原A序列其实表示一个矩阵,而这个矩阵的对角线上的数字就是答案B序列. 接着\(a.b>=gcd(a,b)\),所以序列A中的最大的数就是ans[1],第二大的数就是an ...

随机推荐

  1. c++ 函数后面有个 const

    非静态成员函数后面加const,类似如下函数: class testClass{ public: void testClass() const{ /*...*/} private: /*...*/ } ...

  2. Synchronized知道这些就可以了

    Synchronized关键字算是Java的元老级锁了,一开始它撑起了Java的同步任务,其用法简单粗暴容易上手.但是有些与它相关的知识点还是需要我们开发者去深入掌握的.比如,我们都知道通过Synch ...

  3. DocX 在文档中插入图片时,为什么不能按实际设置的大小插入,而Spire.Doc却可以

    我的目标目标要求:将一个图片插入到页面中,页面边界为0,使用下面的代码去实现(button1UseDocX_Click函数),生成的文档不能达到目的.而使用Spire.Doc却能达到目的button1 ...

  4. Jmeter安装篇(win10)

    参考博文:https://blog.csdn.net/a13124837937/article/details/79628838 以下是我按照参考博文进行的实际操作过程,此篇只为记录,尽量精简内容. ...

  5. 浅谈 MySQL的预编译

    之前的一篇 Mybatis中 #{}和${}的区别 中涉及到通过 SQL预编译和 #{} 传值 的方式防止SQL注入. 由此引发了想了解预编译的想法.那么什么是预编译那? 一.三个阶段: 词法和语义解 ...

  6. H3C版本升级

    H3C S5500和S3100都可以通过TFTP方式进行升级,1.设置交换机的vlan1的ip地址,如10.10.10.2/242.设置电脑和交换机连接的ip地址,如10.10.10.1/243.在交 ...

  7. 【VS开发】【图像处理】基于灰度世界、完美反射、动态阈值等图像自动白平衡算法的原理、实现及效果

    基于灰度世界.完美反射.动态阈值等图像自动白平衡算法的原理.实现及效果      白平衡是电视摄像领域一个非常重要的概念,通过它可以解决色彩还原和色调处理的一系列问题.白平衡是随着电子影像再现色彩真实 ...

  8. input type=file accept中文件格式限制

    原文链接:https://blog.csdn.net/usuallyuser/article/details/83060341 accept="application/msexcel,app ...

  9. c语言Ι博客作业04

    这个作业属于哪个课程 c语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-3/homework/9771 我在这个课程的目 ...

  10. [转帖] 国产x86-海光禅定 2018年营收过亿?

    中科曙光:全年业绩稳健,海光芯片营收过亿 X86服务器市场Intel占据绝对优势:X86处理器已经成为全球最广泛使用的处理器架构之一,尤其是在PC和服务器领域,其中在处理器市场的份额高达90%以上.中 ...