bzoj2144 跳跳棋 二分+lca

这道题刚开始看以为是DP,,,我真是智障了。该DP的看成搜索,该二分的看成DP。。这状态有点危险。。
题意:现在有三个人a,b,c,每一个人可以跳过他左/右边的人,比如说一个人在x,一个在y,那么x可以跳到y+(y-x)(y>x),左边同理。。但是两个人之间不能有另一个人。
现在有三个目标位置和起始位置,让你计算最少的步数让三个人到达目标位置,并不要求人的顺序(即无论哪一个人都可以去任意的终点)。

题解:想法有点神。。果然脑洞还是不够大。
对于每一个状态(x,y,z):
中间的向外面跳->(2x-y,x,z) 或者(x,z,2z-y);
两边往中间跳:当y-x≠z-y时合法,不妨设y-x

type node=record
    x,y,z:longint;
end;
const inf=2147483647;
var
    i,j,len,k,len1,len2:longint;
    l,r,mid:longint;
    a,b,c,d,a1:node;
function min(x,y:longint):longint;
begin
    if xthen exit(x) else exit(y);
end;
function pd(x,y:node):boolean;
begin
    if (x.x=y.x)and(x.y=y.y)and(x.z=y.z) then exit(true)
    else exit(false);
end;
function lca(t:node;x:longint):node;
var
    i,j,u,v:longint;
begin
    len:=0;
    while x<>0 do
    begin
        u:=t.y-t.x;
        v:=t.z-t.y;
        if (u=v)then exit(t);
        if (uthen
        begin
            k:=min((v-1)div u,x);
            t.x:=t.x+k*u;
            t.y:=t.y+k*u;
            x:=x-k;
        end
        else
        begin
            k:=min((u-1)div v,x);
            t.y:=t.y-k*v;
            t.z:=t.z-k*v;
            x:=x-k;
        end;
        len:=len+k;
    end;
    exit(t);
end;
procedure swap(var x,y:longint);
var
    t:longint;
begin
    t:=x;
    x:=y;
    y:=t;
end;
begin
    read(a.x,a.y,a.z);
    if (a.ythen swap(a.x,a.y);
    if (a.zthen swap(a.x,a.z);
    if (a.zthen swap(a.y,a.z); 
    read(b.x,b.y,b.z);
    if (b.ythen swap(b.x,b.y);
    if (b.zthen swap(b.x,b.z);
    if (b.zthen swap(b.y,b.z);
    c:=lca(a,inf);
    len1:=len;
    d:=lca(b,inf);
    len2:=len;  
    if (not pd(c,d))then
    begin
        writeln('NO');
        exit;
    end;
    if (len1then
    begin
        a1:=a;
        a:=b;
        b:=a1;
        swap(len1,len2);
    end;
    a:=lca(a,len1-len2);
    l:=0;
    r:=len2;
    while (ldo
    begin
        mid:=(l+r)>>1;  
        if (pd(lca(a,mid),lca(b,mid)))then
        r:=mid
        else l:=mid+1;  
    end;  
    writeln('YES');
    writeln((l<<1)+len1-len2);
end. 



你可能感兴趣的:(bzoj,二分,lca,做题小结,二分,做题小结,lca,bzoj)