CF995E

双向bfs,至于为什么不会爆还是因为生日悖论,然后双向bfs降低了时空复杂度,ssqrt(n),

然后就是问题的关键

双向bfs:

1.轮流拓展:

会导致一个方向出现了可行解,另一个方向还没出现,无法构成最优,

2.按层拓展:不会出现,ac

3.按size拓展:同1,也会出现该种情况

按size拓展:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<set>
#include<map>
#define LL long long
using namespace std;
const int maxn=5e6+5;//根据生日悖论,只需要找 sqrt(p)次就可以找到答案 
struct Node{
    int num;
    int step;
    int op;
    int pre;
    Node():num(num),step(step),op(op),pre(pre){}
    Node(int _num,int _step,int _op,int _pre){
        num=_num;
        step=_step;
        op=_op;
        pre=_pre;
    }
}q[maxn][2];
LL x,y;
void exgcd(LL a,LL b){
    if(!b){
        x=1ll;
        y=0ll;
        return;
    }
    exgcd(b,a%b);
    LL temp=y;
    y=x-a/b*y;
    x=temp;
} 
inline LL get_inv(LL a,LL p){
    exgcd(a,p);
    return (x%p+p)%p;
}

int u,v;
LL p;

set<int >se[2];//数字
map<int ,int>dis[2]; 

int front[2],rear[2];
void Dfs(int kk){
    if(q[kk][0].pre<0)return;
    
    Dfs(q[kk][0].pre);
    printf("%d ",q[kk][0].op);
}
void Dfs2(int kk){
    if(q[kk][1].pre<0)return;
    
    printf("%d ",q[kk][1].op);
    Dfs2(q[kk][1].pre);
}
inline void bfs(int u,int v){
    
    q[rear[0]++][0]=(Node(u,0,0,-1));//正向 
    q[rear[1]++][1]=(Node(v,0,0,-1));//反向 
    dis[0][u]=dis[1][v]=0;
    se[0].insert(u);
    se[1].insert(v);
    int now=0; 
    while(front[0]<rear[0] || front[1]<rear[1]){
        /*if(rear[0]>maxn ||rear[1]>maxn )
        {
            cout<<"shit";
            exit(0);
        }*/
        //if((front[0]==rear[0] ||q[front[0]][0].step!=now )&& (front[1]==rear[1] || q[front[1]][1].step!=now))now++;
        
        if(rear[0]-front[0]<rear[1]-front[1]){//正向 
            //printf("%d____",front[0]);
            
            Node s=q[front[0]][0];
            
            if(se[1].find(s.num)!=se[1].end()){
                printf("%d\n",s.step+q[dis[1][s.num]][1].step);
                
                Dfs(front[0]);Dfs2(dis[1][s.num]);
                break;
            }
            
            int to=(s.num+1)%p;
            if(se[0].find(to)==se[0].end()){
                dis[0][to]=rear[0];
                q[rear[0]++][0]=(Node(to,s.step+1,1,front[0]));
                se[0].insert(to);
                //printf("%d\n",to);
            }
            
            to=((LL)s.num+p-1)%p;
            if(se[0].find(to)==se[0].end()){
                dis[0][to]=rear[0];
                q[rear[0]++][0]=(Node(to,s.step+1,2,front[0]));
                se[0].insert(to);
                //printf("%d\n",to);
            }
            
            to=get_inv((LL)s.num,p);
            if(se[0].find(to)==se[0].end()){
                dis[0][to]=rear[0];
                q[rear[0]++][0]=(Node(to,s.step+1,3,front[0]));
                se[0].insert(to);//printf("%d\n",to);
            }
            
            front[0]++;
        }
        else {//反向 
        //printf("___%d ",front[1]);
            Node s=q[front[1]][1];
        
            if(se[0].find(s.num)!=se[0].end()){
                printf("%d\n",s.step+q[dis[0][s.num]][0].step);
                 
                Dfs(dis[0][s.num]);Dfs2(front[1]);
                break;
            }
            int to=(s.num+1)%p;
            if(se[1].find(to)==se[1].end()){
                dis[1][to]=rear[1];
                q[rear[1]++][1]=(Node(to,s.step+1,2,front[1]));
                se[1].insert(to);//printf("%d\n",to);
            }
            
            to=((LL)s.num+p-1)%p;
            if(se[1].find(to)==se[1].end()){
                dis[1][to]=rear[1];
                q[rear[1]++][1]=(Node(to,s.step+1,1,front[1]));
                se[1].insert(to);//printf("%d\n",to);
            }
            
            to=get_inv((LL)s.num,p);
            if(se[1].find(to)==se[1].end()){
                dis[1][to]=rear[1];
                q[rear[1]++][1]=(Node(to,s.step+1,3,front[1]));
                se[1].insert(to);//printf("%d\n",to);
            }
            
            front[1]++;
        }
    }
}
int main(){
    scanf("%d%d%lld",&u,&v,&p);
    bfs(u,v);
    
    return ;
}

猜你喜欢

转载自www.cnblogs.com/a-blog-of-taojiayi-2003/p/11267348.html