POJ1808  给定一个方程 x*x==a(mod p) 其中p为质数 判断是否有解

程序中 MOD_sqr()返回整数解 无解返回-1

数学证明略

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#include<algorithm>
using namespace std;
typedef long long int LL; vector<LL>anss;
LL ans[1000000];
LL pow(LL n,LL k,LL p);
inline LL findv(LL x,LL p);
LL GCD(LL a,LL b)//Euclid
{
return b==0?a:GCD(b,a%b);
}
void extend_GCD(LL a,LL b,LL &x,LL &y)//extend Euclid
{
if(b==0){x=1;y=0;}
else {extend_GCD(b,a%b,y,x);y-=a/b*x;}
}
LL line_mod_equation(LL a,LL b,LL n)//二元一次线性不定方程求解
{
LL x,y;
extend_GCD(a,n,x,y);
LL d=GCD(a,n);
if(b%d==0)
{
while(x<0)x+=n;
while(x>n)x-=n;
LL a1=x*(b/d)%(n/d);
while(a1-n/d>0)a1-=n/d;
return a1;//此处只返回最小正整数解 若要解序列 在主函数中生成
}
return -1;
}
LL CRT(int a[],int m[],int n)//中国剩余定理
{
int M=1;
for(LL i=0;i<n;i++)
M*=m[i];
LL ret=0;
for(LL i=0;i<n;i++)
{
LL x,y;
LL tm=M/m[i];
extend_GCD(tm,m[i],x,y);
ret=(ret+tm*x*a[i])%M;
}
while(ret<0)ret+=M;
while(ret>M)ret-=M;
return ret;
}
inline LL findRoot(LL p)
{
LL s=ceil(sqrt(p-1));
for(LL i=1;i<p;i++)
{
if(pow(i,p-1,p)==1)
{
bool sign=1;
for(LL j=2;j<=s;j++)
if(((p-1)%j==0)&&(pow(i,(p-1)/j,p)==1))
{sign=0;break;}
if(sign)return i; }
}
return -1;
}
LL pow(LL n,LL k,LL p)
{
if(k==0)return 1;
LL w=1;
if(k&1)w=n%p;
LL ans=pow(n*n%p,k>>1,p);
return ans*w%p;
}
inline LL ind(LL x,LL p,LL g)//g^y=x(mod p) return y
{
static map<LL,LL>tmp;
LL s=ceil(sqrt(p));
LL w=pow(g,s,p);
for(LL r=0;r<=s;++r)tmp.insert(make_pair(pow(g, r, p), r));
for(LL t=0;t<=s;++t)
{
LL gt=pow(w,t,p);
LL anti=findv(gt,p);
if(tmp.count(x*anti%p))return (tmp[x*anti%p]+t*s); }
return -1;
}
inline LL findv(LL x,LL p)
{
LL d,t;
extend_GCD(x,p,d,t);
while(d<0)d+=p;
return d;
}
LL MOD_sqr(LL a,LL p)//求解 x^2=a(modp)原理有待证明
{
if(p==2)return a%p;
if(pow(a,(p-1)/2,p)!=1)return -1;
LL x;
if(p%4==3)x=pow(a,(p+1)/4,p);
else
{
LL b;
for(b=1;pow(b,(p-1)/2,p)==1;b++);
LL i=(p-1)/2,k=0;
do
{
i>>=1;k>>=1;
if((pow(a,i,p)*pow(b,k,p)+1)%p==0)
{
k+=(p+1)/2;
} }while(i%2==0);
x=pow(a,(i+1)/2,p)*pow(b,k/2,p)%p;
}
if(x*2>p)x=p-x;
return x;
}
int main()
{
freopen("t.txt","r",stdin);
LL np;
scanf("%lld",&np);
for(LL ii=1;ii<=np;ii++)
{
LL a,p;
scanf("%lld%lld",&a,&p);
a=(a%p+p)%p;
LL ans=MOD_sqr(a,p);
if(ans==-1)printf("Scenario #%lld:\n-1\n\n",ii);
else printf("Scenario #%lld:\n1\n\n",ii);
}
return 0;
}

  

最新文章

  1. 11g新特性-使用DNFS
  2. 使用Memcached Session Manager扩展Session管理
  3. python学习之字符串变量
  4. move 和 CopyMemory的区别
  5. shiro连接数据库
  6. winfrom LED时钟
  7. 前端资源多个产品整站一键打包&amp;包版本管理(三)—— gulp分流
  8. Scrapinghub | Professional Services
  9. amchart
  10. 在VS上配置OpenCV
  11. [文学阅读] METEOR: An Automatic Metric for MT Evaluation with Improved Correlation with Human Judgments
  12. 从头开始学JavaScript (五)——操作符(二)
  13. ASP.NET Page执行顺序
  14. flex 访问webservice方法及跨域问题解决
  15. 野路子码农系列(2)Python中的类,可能是最通俗的解说
  16. Python内置函数(15)——dict
  17. CentOS 7下 部署Redis-cluster集群
  18. docker更改默认仓库地址
  19. lelnet爱一直在
  20. java----Java的栈,堆,代码,静态存储区的存储顺序和位置

热门文章

  1. Xshell连接Centos7.5和yum
  2. stm8l定时器中的ARPE
  3. Uva 816 Abbott的复仇(三元组BFS + 路径还原)
  4. cadence中画焊盘注意事项
  5. DD &amp; E-app
  6. noip模拟赛 卖书
  7. node.js里的buffer常见操作,copy,concat等实例讲解
  8. n个点中求任意两点组成斜率的最大值
  9. 洛谷 P3137 [USACO16FEB]圆形谷仓Circular Barn_Silver
  10. JSP的Cookie处理