kZjPBD.jpg

Discrete Roots SPOJ - DISCRT(原根+指标+bsgs+exgcd)

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include"vector"
  4 #include"iostream"
  5 #include <algorithm>
  6 #include"bits/stdc++.h"
  7 using namespace std;
  8 #include"map"
  9 #define ll long long
 10 #define int ll
 11 
 12 int a,b,p;
 13 int k,g;
 14 vector<int >v;
 15 int phi;
 16 vector<int > ans;
 17 
 18 int ksm(int a,int b,int mod)
 19 {
 20     int ans = 1;
 21     for(;b;b>>=1,a*=a,a%=mod)if(b&1)ans*=a,ans%=mod;
 22     return ans;
 23 }
 24 
 25 void fenjie(int x)
 26 {
 27     for(int i=2;i*i<=x;i++)
 28     {
 29         if(x%i==0)v.push_back(i);
 30         while(x%i==0)x/=i;
 31     }
 32     if(x>1) v.push_back(x);
 33 }
 34 
 35 int find_root()
 36 {
 37     for(int i=2;i;i++)
 38     {
 39         int f=1;
 40         for(auto j:v)
 41         {
 42             if(ksm(i,phi/j,p)==1)
 43             {
 44                 f=0;break;
 45             }
 46         }
 47         if(f==1)return i;
 48     }
 49 }
 50 
 51 int bsgs(int a,int b,int p)
 52 {
 53      b%=p;
 54      int m=ceil(sqrt(p));
 55      map<int ,int >mp;
 56      int k=b;
 57      for(int i=0;i<=m;i++)
 58      {
 59          mp[k]=i;
 60          k=k*a%p;
 61      }
 62      int kt=ksm(a,m,p) ;  int now  = 1;
 63 
 64      for(int i=1;i<=m;i++) // 从1开始,否则会出现负数解
 65      {
 66          now=now*kt%p;
 67 
 68      if(mp[now])
 69             return i*m-mp[now];
 70      }
 71      return -1;
 72 }
 73 int exgcd(int a,int b,int &x,int &y)
 74 {
 75     if(!b)x=1,y=0;
 76     else
 77     {
 78         exgcd(b,a%b,y,x),y-=a/b*x;
 79     }
 80 }
 81 
 82 void solve(int a,int b,int p)
 83 {
 84    // cout<<a<<" "<<b<<" " <<p<<endl;
 85     int x,y;
 86     int d=__gcd(a,p);
 87     if(b%d!=0)return ;
 88 
 89     int t=b/d;
 90     exgcd(a,p,x,y);
 91     x%=p,x+=p,x%=p;
 92     x*=t;
 93     //cout<<x<<" "<<b/d<<" "<<p/d<<" "<<d<<endl;
 94     int delta=p/d;
 95     while(x<p)ans.push_back(ksm(g,x,p+1)),x=(x+delta); // 这里要mod p+1, 因为这个函数里的p为phi(p)
 96 
 97 
 98 }
 99 signed main()
100 {
101     cin>>p>>k>>b;  phi=p-1;
102     fenjie(phi);
103     g=find_root();
104     int gb=bsgs(g,b,p);
105 
106     solve(k,gb,phi);
107 
108 
109     sort(ans.begin(),ans.end());
110     ans.erase(unique(ans.begin(),ans.end()),ans.end());
111     cout<<ans.size()<<endl;
112     for(auto i:ans)cout<<i<<" ";
113 
114 
115 
116 
117 }

 

In this problem, we try to compute discrete kth root modulo n; given n, k, a; find all the solutions for x such that xk = a (mod n) and x is coprime with n.

Input

For each input file, there are 3 space seperated integers n, k, a.

n = pe for some odd prime p, integer e > 0; 0 <= a < n <= 109, 0 <= k < phi(n), where phi is Euler's totient function; the numbers n, a are coprimes.

Output

The first line of the output contains a single integer m, the number of solutions in the range [0, n - 1] that are coprimes with n, followed by m lines that contain the m solutions in ascending order. It is guranteed that m <= 104.

Example

Input:
5 1 3

Output:
1
3




这题不错,综合了很多的知识
题解网上一大堆,我就不写了 嘿嘿






















posted @ 2019-05-28 19:48  Through_The_Night  阅读(373)  评论(0)    收藏  举报