二次剩余板子

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<ctime>
#define re register
#define rep(i,s,t) for(re int i=s;i<=t;++i)
using namespace std;
int n,p,T,a,w;
inline int fp(int a,int b){
    int res=1;
    for(;b;b>>=1,a=1ll*a*a%p)
        if(b&1)
            res=1ll*res*a%p;
    return res;
}
struct node{
    int a,b;
    inline node operator*(node A)const{
        node res;
        res.a=(1ll*a*A.a%p+1ll*b*A.b%p*w%p+p)%p;
        res.b=(1ll*b*A.a%p+1ll*a*A.b%p+p)%p;
        return res;
    }
}ans,A;
inline node operator^(node a,int b){
    node res;
    res.a=1,res.b=0;
    for(;b;b>>=1,a=a*a)
        if(b&1)
            res=res*a;
    return res;
}
int main(){
    srand(19260817);
    for(scanf("%d",&T);T--;){
        scanf("%d%d",&n,&p);
        if((fp(n,(p-1)/2)+1)%p==0){
            puts("No ans");
            continue;
        }
        while(1){
            a=rand()%p;
            w=(1ll*a*a-n+p)%p;
            if((fp(w,(p-1)/2)+1)%p==0)
                break;
        }
        //printf("%lld %lld\n",a,w);
        A.a=a,A.b=1;
        ans=(A^((p+1)/2));
        printf("%d\n",ans.a);
    }
    return 0;
}
code

猜你喜欢

转载自www.cnblogs.com/Stump/p/9295879.html