Gym 101138I Prime Moving【素數測試】

Description

standard input/output
Statements

The author of this problem hopes that you already know the pig called Benny.

Recently she started learning numbers. The first type of numbers she has learnt are primes, i.e. positive integers with

 exactly two divisors. First few primes are 2357 and 11. As a homework Benny was given two primes a and b.

 She has to transform a into b using addition and subtraction.Since Benny knows only primes, she might add and

 subtract only primes. Moreover, all the partial results also have to be primes.One move is either adding or

 subtracting a prime to/from the current number. A way of transforming a into bis called optimal if it doesn't 

use more moves than any other way. Your task is to find the only optimal way, if exactly one exists.

If it's impossible to transform a into b, print "Unlucky Benny" (without the quotes). If there are multiple

 optimal ways, print "Poor Benny" (without the quotes). Otherwise output the transformation with all 

partial results. See the output format below.

Input

The only line of the input contains two integers a and b (2 ≤ a < b ≤ 1015). Both a and b are primes.

Output

If the transformation is impossible, print "Unlucky Benny".

If there are many optimal ways, print "Poor Benny".

If there is exactly one optimal way to transform a into b, describe the process in the following format.

 Letx1, x2, ..., xk denote values of Benny's number in the order. So x1 = axk = b and Benny 

changes xi to xi + 1in the i-th move. In a single line print k numbers separated with two 

characters "->", without the quotes and spaces.

Sample Input

Input
5 7
Output
5->7

Hint

One move is enough in the sample.

If the only optimal way was to change 5 to 20, then change 20 to 10, and then finally change 10 to 7,

 the output would be 5->20->10->7. Though, such a way is not only non-optimal but also it isn't valid.

 In the first move (from 5 to 20) we try to add 15 what 

is not prime. Also, a new number 20 isn't prime. This note is only to show you the correct format.



/*
    題意:給你兩個素數a,b,要你僅通過加法或減法只使用素數進行運算從a得到b
          如果不存在方案輸出"Unlucky Benny",如果存在多條最優的方案輸出
          "Poor Benny",否則輸出方案路徑
    類型:素數測試+腦洞
    分析:因爲a,b的範圍在10^15以內,所以要用素數測試算法,這部分可以套模版
          然後就是怎麼做的問題.首先列舉一下素數出來看看
          2 3 5 7 11 13 17 19...
          分兩種情況討論:
          第一種:a=2時,這時候先看b-2是否爲素數,如果是的話我們可以a+b-2得到b
                 所以路徑是2->b;如果b-2不是素數,再看b+2是不是素數,如果是的話,
                 我們可以a+(b+2)-2得到b即2->b+2->b,如果b+2不是素數則無解,因爲
                 不可能存在a+素數k+素數k'+..=b的情況,why?因爲素數k+素數k'就不是
                 素數了(除了2以外,其他素數都是奇數,兩個奇數相加=偶數能被2整除)
          第二種:a!=2時,首先可以確定的是a+2/-2這樣的方式移動,原因上面說過了,並且
                 這裏向一個方向移動的次數<2也就是+2/-2在一個方向是最多進行一次,
                 why?因爲進行兩次相當於a+4/-4而4不是素數.
                 所以一共有這麼幾種情況:
                 a+2=b;(例如5->7)
                 a-(a-2)=2,回到情況一找b;(例如5->2->13)
                 a+2-(a-2)=2,回到情況一找b;(例如3->5->2->13)
          最複雜的情況長度爲5,例如3->5->2->1000000009->1000000007
          另外這道題不存在在最優的情況下有多解,因爲最優是討論-2,再討論+2,只有一條最
          優的路
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const long long S=20;
long long mult_mod(long long a,long long b,long long c){
    a%=c;
    b%=c;
    long long ret=0;
    while(b){
        if(b&1){ret+=a;ret%=c;}
        a<<=1;
        if(a>=c)a%=c;
        b>>=1;
    }
    return ret;
}
long long pow_mod(long long x,long long n,long long mod){
    if(n==1)return x%mod;
    x%=mod;
    long long tmp=x;
    long long ret=1;
    while(n){
        if(n&1) ret=mult_mod(ret,tmp,mod);
        tmp=mult_mod(tmp,tmp,mod);
        n>>=1;
    }
    return ret;
}
bool check(long long a,long long n,long long x,long long t){
    long long ret=pow_mod(a,x,n);
    long long last=ret;
    for(long long i=1;i<=t;i++){
        ret=mult_mod(ret,ret,n);
        if(ret==1&&last!=1&&last!=n-1) return true;
        last=ret;
    }
    if(ret!=1) return true;
    return false;
}
bool Miller_Rabin(long long n){
    if(n<2)return false;
    if(n==2)return true;
    if((n&1)==0) return false;
    long long x=n-1;
    long long t=0;
    while((x&1)==0){x>>=1;t++;}
    for(long long  i=0;i<S;i++){
        long long a=rand()%(n-1)+1;
        if(check(a,n,x,t))
            return false;
    }
    return true;
}
long long factor[1000000];
long long tol;
long long gcd(long long a,long long b){
    if(a==0)return 1;
    if(a<0)return gcd(-a,b);
    while(b){
        long long t=a%b;
        a=b;
        b=t;
    }
    return a;
}
long long Pollard_rho(long long x,long long c){
    long long i=1,k=2;
    long long x0=rand()%x;
    long long y=x0;
    while(1){
        i++;
        x0=(mult_mod(x0,x0,x)+c)%x;
        long long d=gcd(y-x0,x);
        if(d!=1&&d!=x) return d;
        if(y==x0) return x;
        if(i==k){y=x0;k+=k;}
    }
}
void findfac(long long n){
    if(Miller_Rabin(n)){
        factor[tol++]=n;
        return;
    }
    long long p=n;
    while(p>=n)p=Pollard_rho(p,rand()%(n-1)+1);
    findfac(p);
    findfac(n/p);
}
vector<long long>v;
void print(){
    long long len=v.size();
    printf("%I64d",v[0]);
    for(long long  i=1;i<len;i++){
        printf("->%I64d",v[i]);
    }puts("");
}
int main(){
    long long a,b;
    while(scanf("%I64d%I64d",&a,&b)!=EOF){
        if(a==2){
            if(Miller_Rabin(b-2)){
                printf("%I64d->%I64d\n",a,b);
                continue;
            }
            if(Miller_Rabin(b+2))printf("%I64d->%I64d->%I64d\n",a,b+2,b);
            else printf("Unlucky Benny\n");
        }
        else{
            v.clear();v.push_back(a);
            long long t=a;
            while(t<b){
                t+=2;
                if(Miller_Rabin(t)){
                    v.push_back(t);
                    if(t==b)print();
                }
                else{
                    v.clear();v.push_back(a);
                    if(Miller_Rabin(a-2)){
                        v.push_back(2);
                        if(Miller_Rabin(b-2)){
                            v.push_back(b);
                            print();
                            break;
                        }
                        if(Miller_Rabin(b+2)){
                            v.push_back(b+2);v.push_back(b);
                            print();
                            break;
                        }
                    }
                    if(Miller_Rabin(a+2)){
                        v.push_back(a+2);a+=2;
                        if(Miller_Rabin(a-2)){
                            v.push_back(2);
                            if(Miller_Rabin(b-2)){
                                v.push_back(b);
                                print();
                                break;
                            }
                            if(Miller_Rabin(b+2)){
                                v.push_back(b+2);v.push_back(b);
                                print();
                                break;
                            }
                        }
                    }
                    printf("Unlucky Benny\n");
                    break;
                }
            }
        }
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章