• Discrete Roots SPOJ


      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




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






















  • 相关阅读:
    捡到一本<C++ Reference>
    题目1008:最短路径问题
    题目1014:排名
    题目1080:进制转换
    题目1081:递推数列
    题目1086:最小花费
    题目1076:N的阶乘
    题目1035:找出直系亲属
    在Mac上搭建Jenkins环境
    获取鼠标点击UGUI,先对于特定物体的相对坐标
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/10939818.html
Copyright © 2020-2023  润新知