zoukankan      html  css  js  c++  java
  • 【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{egin{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} ight. ]

    我们将一个状态两边向中间转移后的状态设为这个状态的父亲,我们发现,这刚好形成了一颗树。
    那么从起点和终点都分别向父亲跳,用hash判重,如果有交点就输出yes以及ans,反之。
    但这显然会超时。
    我们用二元组(l,r)来代表每一个状态,l=b-a,r=c-b。(显然根节点就是l=r的二元组)
    当这个状态向父亲跳时,就变成

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

    发现这样转移就类似于辗转相除法!
    用倍增求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
    %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
    %lld",ans);
    		else printf("NO");
    }
    
  • 相关阅读:
    多线程中注意事项
    多线程实现第三种方式
    线程池《一》
    线程组
    线程间通信注意的问题
    互斥锁
    多个线程通信的问题
    二个线程间的通信
    死锁产生的原理
    线程安全问题
  • 原文地址:https://www.cnblogs.com/chen1352/p/9045290.html
Copyright © 2011-2022 走看看