URAL1132 Square Root 二次剩余模版题

来源:互联网 发布:qq飞车b车大黄蜂数据 编辑:程序博客网 时间:2024/04/28 15:55

关于二次剩余的介绍:http://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm

二次剩余的模版:

inline ll pow_mod(ll a,ll k,ll mo){ll ans=1;while(k){if(k%2) ans=ans*a%mo;a=a*a%mo;k>>=1;}return ans%mo;}inline int modsqr(int a,int n){int b,k,i,x;if(n==2) return a%n;if(pow_mod(a,(n-1)/2,n)==1){if(n%4==3)x=pow_mod(a,(n+1)/4,n);else{for(b=1;pow_mod(b,(n-1)/2,n)==1;b++);i=(n-1)/2;k=0;do{i/=2;k/=2;if((pow_mod(a,i,n)*(ll)pow_mod(b,k,n)+1)%n==0)k+=(n-1)/2;}while(i%2==0);x=(pow_mod(a,(i+1)/2,n)*(ll)pow_mod(b,k/2,n))%n;}if(x*2>n) x=n-x;return x;}return -1;}

此题在n==2的时候特判一下答案就可以了。

#include<cstdio>#define ll long longinline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}inline ll pow_mod(ll a,ll k,ll mo){ll ans=1;while(k){if(k%2) ans=ans*a%mo;a=a*a%mo;k>>=1;}return ans%mo;}inline int modsqr(int a,int n){int b,k,i,x;if(n==2) return a%n;if(pow_mod(a,(n-1)/2,n)==1){if(n%4==3)x=pow_mod(a,(n+1)/4,n);else{for(b=1;pow_mod(b,(n-1)/2,n)==1;b++);i=(n-1)/2;k=0;do{i/=2;k/=2;if((pow_mod(a,i,n)*(ll)pow_mod(b,k,n)+1)%n==0)k+=(n-1)/2;}while(i%2==0);x=(pow_mod(a,(i+1)/2,n)*(ll)pow_mod(b,k/2,n))%n;}if(x*2>n) x=n-x;return x;}return -1;}int main(){int a,n,t;t=read();while(t--){a=read();n=read();int ans=modsqr(a,n);if(ans==-1) puts("No root");else if(n==2) puts("1");else printf("%d %d\n",ans,n-ans);}}


0 0
原创粉丝点击