【BZOJ2144】Throw 数论
题目大意
给你三个数\(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)\)只能有三种转移:
\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 数论的更多相关文章
- 数学概念——I - 数论,线性方程
		
I - 数论,线性方程 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit ...
 - 浅谈Java的throw与throws
		
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
 - C++异常处理:try,catch,throw,finally的用法
		
写在前面 所谓异常处理,即让一个程序运行时遇到自己无法处理的错误时抛出一个异常,希望调用者可以发现处理问题. 异常处理的基本思想是简化程序的错误代码,为程序键壮性提供一个标准检测机制. 也许我们已经使 ...
 - Codeforces Round #382  Div. 2【数论】
		
C. Tennis Championship(递推,斐波那契) 题意:n个人比赛,淘汰制,要求进行比赛双方的胜场数之差小于等于1.问冠军最多能打多少场比赛.题解:因为n太大,感觉是个构造.写写小数据, ...
 - java中的throw与throws的区别
		
什么时运行时异常?什么是非运行时异常? 通俗的讲: 运行时异常:就是编译通过,运行时就崩了,比如数组越界. 非运行时异常:就是编译不通过,这时就得必须去处理了.不然就没法运行了. 全面的讲: Thro ...
 - js 利用throw 写的一个小程序
		
在下边的小程序中比较特殊的是使用isNaN()函数判断一个参数是不是数字, <!DOCTYPE html> <!DOCTYPE html> <html> <h ...
 - C++异常处理: try,catch,throw,finally的用法
		
写在前面 所谓异常处理,即让一个程序运行时遇到自己无法处理的错误时抛出一个异常,希望调用者可以发现处理问题. 异常处理的基本思想是简化程序的错误代码,为程序键壮性提供一个标准检测机制. 也许我们已经使 ...
 - Java 中 手动抛出异常: throw new Exception("错误信息") 错误信息的获得
		
当然需要先用try catch捕获,但注意new Exception("")括号里的字符串其实是异常原因,所以获取是要用ex.getCause().getMessage() int ...
 - NOIP2014 uoj20解方程 数论(同余)
		
又是数论题 Q&A Q:你TM做数论上瘾了吗 A:没办法我数论太差了,得多练(shui)啊 题意 题目描述 已知多项式方程: a0+a1x+a2x^2+..+anx^n=0 求这个方程在[1, ...
 
随机推荐
- shell 小工具
			
1.打印进度条(待完善) #!/bin/sh printf -- 'Performing asynchronous action..'; DONE=; printf -- '............. ...
 - C++常用代码优化策略
			
C++代码常用的优化策略 1.不存在指向空值的引用,意味着引用比指针的效率更高,因为在使用引用之前不需要测试它的合法性:指针可以被重新赋值以指向另一个不同的对象,但是引用总是指向它初始化时指定的对象. ...
 - Python-Urllib库详解
			
官方文档地址:https://docs.python.org/3/library/urllib.html 什么是Urllib: Urllib是python内置的HTTP请求库: urllib.requ ...
 - Python-sys模块-61
			
sys 模块:和Python解释器打交道的模块 sys模块是与python解释器交互的一个接口 sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退 ...
 - H5 17-兄弟选择器
			
17-兄弟选择器 我是标题 我是超链接 我是段落 我是段落 我是段落 我是标题 我是段落 我是段落 我是段落 --> 我是标题 我是超链接 我是段落 我是段落 我是超链接 我是段落 我是标题 我 ...
 - 关于js作用域问题
			
补充: function Foo(name,age){ this.name=name; this.age=age; this.getName=function(){ console.log(this) ...
 - [转帖]国产紫光SSD不再只是实验室展品 开始批量出货
			
国产紫光SSD不再只是实验室展品 开始批量出货 https://www.cnbeta.com/articles/tech/825865.htm 没听说有做HDD的 现做了SSD 弯道超车吗 可以实现全 ...
 - Eclipse的DEgub调试乱跳
			
去掉勾选,是软件的BUG
 - python爬虫之Gerapy安装部署
			
原创北航大才:https://cuiqingcai.com/5006.html NULL:http://www.infosec-wiki.com/?p=432737
 - python数据结构与算法第九天【选择排序】
			
1.选择排序的原理 2.代码实现 def selection_sort(alist): n = len(alist) # 需要进行n-1次选择操作 for i in range(n-1): # 记录最 ...