【NOIP模拟】丢你拉姆

题面

分析

太困难了TAT,暴搜的20分都没搜对。

其实原题是跳跳棋,只能说有些人py能力太强,题面都改成这样都能找出来。。

我们考虑一个有序状态 S(x ,y, z),x<=y<=z。观察他的转移方案:
设 l = y-x, r = z-y。
1. 中间向两边跳 S(x, y, z) - S(x-l, y-l, z), S(x, y, z) - S(x, y-z, z-r)
2. 两边向中间,
  𝐥 < 𝐫, 𝐒(𝐲,𝐳,𝐴) – 𝐒(𝐲 + 𝐥,𝐳 + 𝐥,𝐴)
  𝐥 > 𝐫, 𝐒(𝐲,𝐳,𝐴) – 𝐒(𝐲,𝐳 − 𝐫,𝐴 − 𝐫)
由于转移时可逆的。我们将一个状态两边向中间转移后的状态设为这个状态的父亲,我们发现,这刚好形成了一颗树!
然后问题就变成了询问两点间的距离。由于得不出树的形态,我们可以先让其中一个节点先跳到根另一个节点在一个个往上跳,看有没有交集,如果到根都没有交集就是无解
优化:
我们可以用倍增的思想来实现向上跳的操作。
由于树的深度可能会很大,所以我们无法把倍增的数组求出来,需要动
态访问倍增数组。我们可以令二元组(a, b)代替状态 S,a=y-x, b=z-y 且 a>b。
那么显然状态 S 的父亲 SS(xx, yy, zz)满足 yy-xx=a-b, zz-yy=b,也就是说一个状态向上跳二元组(a, b)就会变成(a-b, b),这像什么?更相减损术!那么就可以用辗转相除的思想加速到 O(Logb)

INF不能取大了,不然就等着着莫名WA几发吧

代码

 

#include<bits/stdc++.h>  
using namespace std;  
#define N 5  
#define INF 0x3f3f3f3f  
int d1,d2,d3,rets,retd,tmp,ans;  
struct email  
{  
    int x[N];  
    void read(){for(int i=1;i<=3;i++)scanf("%d",&x[i]);}  
    bool operator !=(const email &a)const  
    {return x[1]!=a.x[1]||x[2]!=a.x[2]||x[2]!=a.x[2];}  
}st,ed;  
email cal(const email &a,int k,int &ret)  
{  
    email ans=a;  
    int dis1=a.x[2]-a.x[1],dis2=a.x[3]-a.x[2];  
    if(dis1==dis2)return ans;  
    else if(dis1<dis2)  
    {  
        int t=min(k,(dis2-1)/dis1);  
        k-=t;ret+=t;  
        ans.x[2]+=t*dis1,ans.x[1]+=t*dis1;  
    }  
    else  
    {  
        int t=min(k,(dis1-1)/dis2);  
        k-=t;ret+=t;  
        ans.x[2]-=t*dis2,ans.x[3]-=t*dis2;  
    }  
    if(k)return cal(ans,k,ret);  
    else return ans;  
}  
int main()  
{  
    st.read();ed.read();  
    sort(st.x+1,st.x+4);sort(ed.x+1,ed.x+4);  
    email rs=cal(st,INF,rets),rd=cal(ed,INF,retd);  
    if(rs!=rd){printf("NO\n");return 0;}  
    printf("YES\n");  
    if(rets>retd)swap(rets,retd),swap(st,ed);  
    ans=retd-rets;  
    ed=cal(ed,ans,tmp);  
    int l=0,r=rets,mid;  
    while(l<=r)   
    {  
        mid=l+r>>1;  
        if(cal(st,mid,tmp)!=cal(ed,mid,tmp))l=mid+1;  
        else r=mid-1;  
    }  
    printf("%d\n",ans+2*l);   
    return 0;             
}  

 

posted @ 2018-10-29 21:00  HappyJoy  阅读(309)  评论(0)    收藏  举报