• POJ1808 平方(二次)同余方程


    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:
    -1
    
    ",ii);
           else printf("Scenario #%lld:
    1
    
    ",ii);
       }
     return 0;
    }
    

      

  • 相关阅读:
    1-4个人博客
    大二上学期软件工程概论学习进度表(第十六周)
    软件工程概论个人总结
    python+selenium 定位元素的主要方法
    python+selenium 元素定位--iframe
    返回字符串中出现最多的字符
    TestNG中 ITestListener 的使用
    对数组对象按某些属性排序方法
    OSX 10.11 cocoapods安装命令: sudo gem install -n /usr/local/bin cocoapods
    IOS启动页设置适应ios8/9
  • 原文地址:https://www.cnblogs.com/heisenberg-/p/6587933.html
Copyright © 2020-2023  润新知