NJUST1722(大数分解的应用)

 

NJUST1722(大数分解的应用)

分类: 数论   125人阅读  评论(0)  收藏  举报

题目:所有的平方差


题意:n = a1*a1 - b1*b1, n = a2*a2 - b2*b2, ... , n = am*am - bm*bm

其中对于任意的1<=k1,k2<=m,ak1 != ak2 或者 bk1 != bk2,并且ak1,ak2,bk1,bk2>=0

那么我们需要求的是n^(a1*a1+b1*b1+a2*a2+b2*b2+...+am*am+bm*bm)%大质数10000000019的值。


本题注意一点,由于10000000019很大,就是最后求出来的ak与ak在相乘的时候注意一下,比如ak大于10^10时,直接相乘

就会爆LL,我们这里有技巧,就是把乘法变为加法,二分加法,也就是下面的multi函数。


通过本题学到了一招,就是对于求x*x%MOD怎么处理,x与MOD大于10^10。


[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <algorithm>  
  5. #include <iostream>  
  6. #include <math.h>  
  7.   
  8. using namespace std;  
  9. typedef unsigned long long LL;  
  10.   
  11. const LL Times=10;  
  12. const LL N=555;  
  13. const LL MOD=10000000018;  
  14.   
  15. LL ct,cnt,c,n;  
  16. LL fac[N],num[N];  
  17. LL arr[N];  
  18.   
  19. LL gcd(LL a,LL b)  
  20. {  
  21.     return b? gcd(b,a%b):a;  
  22. }  
  23.   
  24. LL multi(LL a,LL b,LL m)  
  25. {  
  26.     LL ans=0;  
  27.     while(b)  
  28.     {  
  29.         if(b&1)  
  30.         {  
  31.             ans=(ans+a)%m;  
  32.             b--;  
  33.         }  
  34.         b>>=1;  
  35.         a=(a+a)%m;  
  36.     }  
  37.     return ans;  
  38. }  
  39.   
  40. LL quick_mod(LL a,LL b,LL m)  
  41. {  
  42.     LL ans=1;  
  43.     a%=m;  
  44.     while(b)  
  45.     {  
  46.         if(b&1)  
  47.         {  
  48.             ans=multi(ans,a,m);  
  49.             b--;  
  50.         }  
  51.         b>>=1;  
  52.         a=multi(a,a,m);  
  53.     }  
  54.     return ans;  
  55. }  
  56.   
  57. bool Miller_Rabin(LL n)  
  58. {  
  59.     if(n==2) return true;  
  60.     if(n<2||!(n&1)) return false;  
  61.     LL a,m=n-1,x,y;  
  62.     int k=0;  
  63.     while((m&1)==0)  
  64.     {  
  65.         k++;  
  66.         m>>=1;  
  67.     }  
  68.     for(LL i=0; i<Times; i++)  
  69.     {  
  70.         a=rand()%(n-1)+1;  
  71.         x=quick_mod(a,m,n);  
  72.         for(LL j=0; j<k; j++)  
  73.         {  
  74.             y=multi(x,x,n);  
  75.             if(y==1&&x!=1&&x!=n-1) return false;  
  76.             x=y;  
  77.         }  
  78.         if(y!=1) return false;  
  79.     }  
  80.     return true;  
  81. }  
  82.   
  83. LL Pollard_rho(LL n,LL c)  
  84. {  
  85.     LL x,y,d,i=1,k=2;  
  86.     y=x=rand()%(n-1)+1;  
  87.     while(true)  
  88.     {  
  89.         i++;  
  90.         x=(multi(x,x,n)+c)%n;  
  91.         d=gcd((y-x+n)%n,n);  
  92.         if(1<d&&d<n) return d;  
  93.         if(y==x) return n;  
  94.         if(i==k)  
  95.         {  
  96.             y=x;  
  97.             k<<=1;  
  98.         }  
  99.     }  
  100. }  
  101.   
  102. void find(LL n,LL c)  
  103. {  
  104.     if(n==1) return;  
  105.     if(Miller_Rabin(n))  
  106.     {  
  107.         fac[ct++]=n;  
  108.         return ;  
  109.     }  
  110.     LL p=n;  
  111.     LL k=c;  
  112.     while(p>=n) p=Pollard_rho(p,c--);  
  113.     find(p,k);  
  114.     find(n/p,k);  
  115. }  
  116.   
  117. void dfs(LL dept,LL product=1)  
  118. {  
  119.     if(dept==cnt)  
  120.     {  
  121.         if(product<=(LL)sqrt(1.0*n)&&(product+n/product)%2==0&&(n/product-product)%2==0)  
  122.             arr[c++]=product;  
  123.         return;  
  124.     }  
  125.     for(LL i=0; i<=num[dept]; i++)  
  126.     {  
  127.         dfs(dept+1,product);  
  128.         product*=fac[dept];  
  129.     }  
  130. }  
  131.   
  132. int main()  
  133. {  
  134.     LL t,tt=1;  
  135.     LL ans,x,y;  
  136.     cin>>t;  
  137.     while(t--)  
  138.     {  
  139.         cin>>n;  
  140.   
  141.         printf("Case %d: ",tt++);  
  142.         if(n==1)  
  143.         {  
  144.             puts("1");  
  145.             continue;  
  146.         }  
  147.         ct=0;  
  148.         c=0;  
  149.         find(n,120);  
  150.         sort(fac,fac+ct);  
  151.         num[0]=1;  
  152.         LL k=1;  
  153.         for(LL i=1; i<ct; i++)  
  154.         {  
  155.             if(fac[i]==fac[i-1])  
  156.                 ++num[k-1];  
  157.             else  
  158.             {  
  159.                 num[k]=1;  
  160.                 fac[k++]=fac[i];  
  161.             }  
  162.         }  
  163.         cnt=k;  
  164.         dfs(0,1);  
  165.         sort(arr,arr+c);  
  166.         ans=0;  
  167.         for(LL i=0; i<c; i++)  
  168.         {  
  169.             x=(n/arr[i]+arr[i])/2;  
  170.             y=(n/arr[i]-arr[i])/2;  
  171.             ans+=multi(x,x,MOD)+multi(y,y,MOD);  
  172.             ans%=MOD;  
  173.         }  
  174.         if(c>0) cout<<quick_mod(n,ans,MOD+1)<<endl;  
  175.         else    puts("-1");  
  176.     }  
  177.     return 0;  
  178. }  

你可能感兴趣的:(数论)