zoukankan      html  css  js  c++  java
  • 【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))只能有三种转移:

    [(a,b,c) ightarrow egin{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
    ");
    		return 0;
    	}
    	if(getmid(a,b,c)!=getmid(x,y,z))
    	{
    		printf("NO
    ");
    		return 0;
    	}
    	printf("YES
    ");
    	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
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Java单例模式(Singleton)以及实现
    golang 垃圾回收机制
    MySQL索引背后的数据结构及算法原理
    简述拥塞控制的四种基本算法
    分库分表
    lvalue & rvalue
    理解linux cpu load
    android使用百度地图SDK获取定位信息
    iOSUIWebView---快停下啦,你的愚蠢的行为
    【翻译自mos文章】当/var/tmp文件夹被remove掉之后,GI crash,并启动失败,原因是ohasd can not create named pipe
  • 原文地址:https://www.cnblogs.com/ywwyww/p/8513275.html
Copyright © 2011-2022 走看看