题目大意

  给你三个数\(a,b,c\),每次你可以选择一个数\(s_1\),再选择一个数\(s_2\),把\(s_1\)变成\(2s_2-s_1\),但要求\(s_3\)不在\(s_1\)到\(2s_2-s_1\)之间。

  再给你三个数\(x,y,z\),问你是否能把\(a,b,c\)变成\(x,y,z\)。

  \(|a|,|b|,|c|,|x|,|y|,|z|\leq {10}^9\)

题解

  首先三个数\(a,b,c(a<b<c)\)只能有三种转移:

\[(a,b,c)\rightarrow
\begin{cases}
(2a-b,a,c)\\
(a,c,2c-b)\\
(b,2b-a,c)~~~~~(c-b>b-a)\\
(a,2b-c,b)~~~~~(c-b<b-a)
\end{cases}
\]

  可以发现,这些状态构成了一棵树。

  转移可以用辗转相除法加速。

  直接暴力往上跳找LCA即可。

  时间复杂度:\(O(\log (\max_a-\min_a))\)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void sort(ll &a,ll &b,ll &c)
{
if(b<a)
swap(a,b);
if(c<a)
swap(a,c);
if(c<b)
swap(b,c);
}
void open(const char *s)
{
#ifdef DEBUG
char str[100];
sprintf(str,"%s.in",s);
freopen(str,"r",stdin);
sprintf(str,"%s.out",s);
freopen(str,"w",stdout);
#endif
}
ll gcd(ll a,ll b)
{
return b?gcd(b,a%b):a;
}
ll getmid(ll a,ll b,ll c)
{
while(b-a!=c-b)
if(b-a>c-b)
{
ll j=(b-a)/(c-b);
ll k=c-b;
c-=j*k;
b-=j*k;
if(b==a)
{
b+=k;
c+=k;
}
}
else
{
ll j=(c-b)/(b-a);
ll k=b-a;
a+=j*k;
b+=j*k;
if(b==c)
{
b-=k;
a-=k;
}
}
return b;
}
pll a1[110];
int d1[110];
pll a2[110];
int d2[110];
int cnt1,cnt2;
int main()
{
open("c");
ll a,b,c,x,y,z;
scanf("%lld%lld%lld%lld%lld%lld",&a,&b,&c,&x,&y,&z);
sort(a,b,c);
sort(x,y,z);
if(gcd(b-a,c-b)!=gcd(y-x,z-y))
{
printf("NO\n");
return 0;
}
if(getmid(a,b,c)!=getmid(x,y,z))
{
printf("NO\n");
return 0;
}
printf("YES\n");
pll s1(b-a,c-b);
pll s2(y-x,z-y);
cnt1=cnt2=0;
d1[0]=d2[0]=0;
while(s1.first!=s1.second)
{
a1[++cnt1]=s1;
if(s1.first>s1.second)
{
d1[cnt1]=s1.first/s1.second;
s1.first%=s1.second;
if(!s1.first)
{
s1.first=s1.second;
d1[cnt1]--;
}
}
else
{
d1[cnt1]=s1.second/s1.first;
s1.second%=s1.first;
if(!s1.second)
{
s1.second=s1.first;
d1[cnt1]--;
}
}
}
a1[++cnt1]=s1;
d1[cnt1]=0;
reverse(a1+1,a1+cnt1+1);
reverse(d1+1,d1+cnt1+1);
while(s2.first!=s2.second)
{
a2[++cnt2]=s2;
if(s2.first>s2.second)
{
d2[cnt2]=s2.first/s2.second;
s2.first%=s2.second;
if(!s2.first)
{
s2.first=s2.second;
d2[cnt2]--;
}
}
else
{
d2[cnt2]=s2.second/s2.first;
s2.second%=s2.first;
if(!s2.second)
{
s2.second=s2.first;
d2[cnt2]--;
}
}
}
a2[++cnt2]=s2;
d2[cnt2]=0;
reverse(a2+1,a2+cnt2+1);
reverse(d2+1,d2+cnt2+1);
ll ans=0;
int i,j;
for(i=1;i<=cnt1;i++)
d1[i]+=d1[i-1];
for(i=1;i<=cnt2;i++)
d2[i]+=d2[i-1];
i=cnt1,j=cnt2;
while(a1[i-1]!=a2[j-1])
if(d1[i-1]>d2[j-1])
{
ans+=d1[i]-d1[i-1];
i--;
}
else
{
ans+=d2[j]-d2[j-1];
j--;
}
if(a1[i].first==a2[j].first||a1[i].second==a2[j].second)
{
if(d1[i]>d2[j])
ans+=d1[i]-d2[j];
else
ans+=d2[j]-d1[i];
}
else
ans+=d1[i]-d1[i-1]+d2[j]-d2[j-1];
printf("%lld\n",ans);
return 0;
}

【BZOJ2144】Throw 数论的更多相关文章

  1. 数学概念——I - 数论,线性方程

    I - 数论,线性方程 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit  ...

  2. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  3. C++异常处理:try,catch,throw,finally的用法

    写在前面 所谓异常处理,即让一个程序运行时遇到自己无法处理的错误时抛出一个异常,希望调用者可以发现处理问题. 异常处理的基本思想是简化程序的错误代码,为程序键壮性提供一个标准检测机制. 也许我们已经使 ...

  4. Codeforces Round #382 Div. 2【数论】

    C. Tennis Championship(递推,斐波那契) 题意:n个人比赛,淘汰制,要求进行比赛双方的胜场数之差小于等于1.问冠军最多能打多少场比赛.题解:因为n太大,感觉是个构造.写写小数据, ...

  5. java中的throw与throws的区别

    什么时运行时异常?什么是非运行时异常? 通俗的讲: 运行时异常:就是编译通过,运行时就崩了,比如数组越界. 非运行时异常:就是编译不通过,这时就得必须去处理了.不然就没法运行了. 全面的讲: Thro ...

  6. js 利用throw 写的一个小程序

    在下边的小程序中比较特殊的是使用isNaN()函数判断一个参数是不是数字, <!DOCTYPE html> <!DOCTYPE html> <html> <h ...

  7. C++异常处理: try,catch,throw,finally的用法

    写在前面 所谓异常处理,即让一个程序运行时遇到自己无法处理的错误时抛出一个异常,希望调用者可以发现处理问题. 异常处理的基本思想是简化程序的错误代码,为程序键壮性提供一个标准检测机制. 也许我们已经使 ...

  8. Java 中 手动抛出异常: throw new Exception("错误信息") 错误信息的获得

    当然需要先用try catch捕获,但注意new Exception("")括号里的字符串其实是异常原因,所以获取是要用ex.getCause().getMessage() int ...

  9. NOIP2014 uoj20解方程 数论(同余)

    又是数论题 Q&A Q:你TM做数论上瘾了吗 A:没办法我数论太差了,得多练(shui)啊 题意 题目描述 已知多项式方程: a0+a1x+a2x^2+..+anx^n=0 求这个方程在[1, ...

随机推荐

  1. leveldb和fork的初始化顺序

    我们服务器内用leveldb存一些不是很重要的, 但是又需要(半)持久化的东西. 可是自从2016到现在, 碰见好几次不同类型的死锁. 直到今天, 才发现真正的原因, 那就是leveldb不支持for ...

  2. POJ - 1177 线段树

    POJ - 1177 扫描线 这道题也算是一道扫描线的经典题目了. 只不过这道题是算周长,非常有意思的一道题.我们已经知道了,一般求面积并,是如何求的,现在我们要把扫描线进行改造一下,使得能算周长. ...

  3. SPA单页面优缺点

    优点: 1.体验好,不刷新,减少 请求  数据ajax异步获取 页面流程: 2.前后端分离 3.减轻服务端压力 4.共用一套后端程序代码,设配多端 缺点: 1.首屏加载过慢: 2.SEO 不利于搜索引 ...

  4. sso单点登录系统(解决session共享)

    场景:假设一个用户将自己的登录信息提交到后台,如果session保存的信息分布在多台机器上,并且不共享,那么可能导致用户的登录信息出现短暂的丢失,为什么这样讲,因为用户访问服务器中间还要经过负载均衡服 ...

  5. Python之列表

    一.列表的特点 列表也是一种数据类型 列表元素是有序的,有编号的 列表元素的下标从0开始 列表中的每一个值叫一个元素,编号叫下标(索引/角标): stu_name=['崔海龙','杨帆','lrx', ...

  6. Docker -d : Running modprobe bridge nf_nat failed with message: exit status 1

    nf_nat 是做什么用的 - DockOne.iohttp://dockone.io/question/1384 docker-py的配置与使用 - openxxs - 博客园http://www. ...

  7. jvisualvm远程监控 visualgc插件 不受此jvm支持问题

    https://yq.aliyun.com/ziliao/478212 1.修改远程服务器上java设置 vi $JAVA_HOME/jre/lib/security/java.policy    在 ...

  8. centos 检测aufs 并安装

    http://www.cnblogs.com/logo-fox/p/7366506.html 因为DeviceMapper不稳定,所以必须升级到3.10以上的内核,运行docker(2.6提示运行do ...

  9. 优化MySQL性能的几种方法-总结

    原文:http://bbs.landingbj.com/t-0-245601-1.html 1.要选取最适用的字段属性 MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越 小,在它上 ...

  10. gulp项目和webpack项目在浏览器中查看的方式

    在存在.git的目录下,按住shift+左键,打开命令行或者使用git Bash Gulp: 输入gulp dev 本地起一个服务器,在项目中找到gulp.js,然后找本地服务器,找到host和por ...