歌名 - 歌手
0:00

    【NOIP2016提高A组模拟8.15】Throw

    题目

    这里写图片描述

    分析

    首先对于一个状态(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");
    }
    
    posted @ 2018-05-16 12:10  无尽的蓝黄  阅读(144)  评论(0编辑  收藏  举报