Discrete Roots

题目描述

题解

首先考虑非余数情况下
\(x^k=A \rightarrow ln(x^k)=lnA \rightarrow x=e^{\frac{lnA}{k}}=A^{\frac{1}{k}}\)

在余数下,ln可以转换为ind指标形式

\(k\cdot ind(x)\equiv ind(A) \: \:(mod\:\: P-1)\)
求出ind(A)后上式就是一个一元一次模方程组\(k\cdot x+(P-1)\cdot y=ind(A)\)
用exgcd即可求出ind(x),成立当且仅当(k,P-1)| ind(A)
求出特解x,现在要求的所有的解,我们可以通过不断的向上调整 𝑦 来得到所有的 𝑥,
因为\(0\leq x \leq P-1\),所以x在向上调整过程中模P-1是有周期的,用map记录下就行
最后\(x\equiv g^{ind(x)} (mod \: P)\)

所以本题分为三步
首先求出P意义下的原根g
再用BSGS求ind(A)
用exgcd求出ind(x)
最后再求出x

点击查看代码
 #include<functional>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<complex>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<deque>
#include<map>
#define ll long long 
using namespace std;
const int maxn=1e6+10101;
const int MOD=998244353;
const int inf=2147483647;
const double pi=acos(-1);
ll read(){
    ll x=0,f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
    return x*f;
}
ll power(ll x,ll y,ll mod){
    ll ans=1;
    while(y){
        if(y&1)ans=ans*x%mod;
        y>>=1;x=x*x%mod;
    }
    return ans;
}
void exgcd(ll a,ll b,ll &d,ll &x,ll &y){
    if(!b){d=a;x=1ll;y=0ll;return;}
    exgcd(b,a%b,d,x,y);
    ll t=x;x=y;y=t-(a/b)*y;
    return ;
}
ll BSGS(ll g,ll x,ll p){
    if(x==1)return 0;
    ll B=sqrt(p)+1;
    map<ll,int>ji;
    for(ll b=0,t=x;b<=B;b++,t=t*g%p)ji[t]=b;
    for(ll a=1,t=power(g,B,p),tt=t;a<=B;a++,tt=t*tt%p){
        if(ji[tt])return a*B-ji[tt];
    }
    return 0;
}
vector<ll> cal(ll k,ll phi,ll t){
    vector<ll>ans;
    ll x,y,d;
    exgcd(k,phi,d,x,y);
    if(t%d)return ans;
    ll now=phi/d;
    x=(x*(t/d)%now+now)%now;
    map<ll,ll>ji;
    for(int i=0;i<d;i++){
        if(ji[(x+(ll)i*now)%phi])break;
        ans.push_back(x+(ll)i*now);
        ji[(x+(ll)i*now)%phi]=1;
    }
    return ans;
}
ll p,k,a,phi,g,ind;
ll getroot(){
    phi=p-1;vector<ll>zhi;
    for(ll i=2;i*i<=phi;i++){
        if(phi%i==0){
            zhi.push_back(i);
            while(phi%i==0)phi/=i;
        }
    }
    if(phi>1)zhi.push_back(phi);
    for(int i=1;i<p;i++){
        ll d,x,y;exgcd(i,p,d,x,y);
        if(d!=1)continue;
        bool fa=true;
        for(auto j:zhi){
            if(power(i,(p-1)/j,p)==1){fa=!fa;break;}
        }
        if(fa)return i;
    }
    return 0ll;
}
int main(){
    p=read();k=read();a=read();
    if(a==0){printf("1\n0");return 0;}
    g=getroot(); //求原根
    ind=BSGS(g,a,p);   //求ind(A)
    auto ans=cal(k,p-1,ind); //求ind(x)
    for(int i=0;i<ans.size();i++)ans[i]=power(g,ans[i],p);
    sort(ans.begin(),ans.end());
    printf("%lu\n",ans.size());
    for(auto i:ans)printf("%lld ",i);
    return 0;
}

posted @ 2022-01-03 15:21  I_N_V  阅读(58)  评论(0编辑  收藏  举报