• 【模板】原根


    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    
    // Parameter: N
    // Method: init()!!! solve(x)
    // Output: sorted list of proot (returned)
    namespace proot {
    const int N=1e6+5;
    int pr[N+5];
    bool check[N+5];
    int phi[N+5];
    int num;
    
    void init() {
        memset(check, false, sizeof(check));
        phi[1]=1;
        for(int i=2; i<=N; i++) {
            if(!check[i]) {
                pr[num++]=i;
                phi[i]=i-1;
            }
            for(int j=0; j<num; j++) {
                if(i*pr[j]>N) break;
                check[i*pr[j]]=true;
                if(i%pr[j]==0) {
                    phi[i*pr[j]]=phi[i]*pr[j];
                    break;
                } else {
                    phi[i*pr[j]]=phi[i]*(pr[j]-1);
                }
            }
        }
    }
    
    void get(int n,vector<int>& fac) {
        fac.clear();
        for(int i=2; i*i<=n; i++)
            if(n%i==0) {
                fac.push_back(i);
                while(n%i==0) n/=i;
            }
        if(n>1) fac.push_back(n);
    }
    
    int qpow(int x,int n,int mod) {
        int ret=1;
        for(; n; n>>=1) {
            if(n&1) ret=ret*x%mod;
            x=x*x%mod;
        }
        return ret;
    }
    
    vector<int> fac,ans;
    
    bool ok(int x) {
        if(x%2==0) x/=2;
        if(x%2==0) return false;
        for(int i=0; pr[i]*pr[i]<=x; i++) if(x%pr[i]==0) {
                while(x%pr[i]==0) x/=pr[i];
                return x==1;
            }
        return true;
    }
    
    int get_g(int p) {
        for(int i=2; i<p; i++) {
            bool flag=false;
            for(int x:fac)
                if(qpow(i,phi[p]/x,p)==1) {
                    flag=true;
                    break;
                }
            if(!flag&&qpow(i,phi[p],p)==1)  return i;
        }
    }
    
    void GetAns(int g,int p,vector<int>& ans) {
        ans.clear();
        ans.push_back(g);
        for(int i=2; i<phi[p]; i++)
            if(__gcd(i,phi[p])==1) ans.push_back(qpow(g,i,p));
    }
    
    vector<int> solve(int p) {
        init();
        if(p==2||p==4) return vector<int>{p-1};
        if(!ok(p)) return vector<int>{};
        get(phi[p],fac);
        int g=get_g(p);
        GetAns(g,p,ans);
        sort(ans.begin(),ans.end());
        return ans;
    }
    }
    
    signed main() {
        int T,x,d;
        ios::sync_with_stdio(false);
        proot::init();
        cin>>T;
        while(T--) {
            cin>>x>>d;
            vector <int> ans=proot::solve(x);
            cout<<ans.size()<<endl;
            for(int i=d;i<=ans.size();i+=d) cout<<ans[i-1]<<" ";
            cout<<endl;
        }
    }
    
    /*
    4
    25 2 36 1 9 6 18 1
    [Output]
    8
    3 12 17 23
    0
    
    2
    
    2
    5 11
    */
    
  • 相关阅读:
    Layui表格之动态添加数据(表格多选解决方案)
    Ztree勾选节点后取消勾选其父子节点
    如何判断某个元素在页面上是否存在
    Linux环境搭建SVN服务
    Linux环境下验证码不显示F12报500
    Ztree节点前加上两个自定义按钮
    解决window.location.href参数太长
    Ztree加载完成默认选中根节点右侧生成表格
    输入框点击下滑Ztree菜单
    Mybatis中and和or的细节处理
  • 原文地址:https://www.cnblogs.com/mollnn/p/12344212.html
Copyright © 2020-2023  润新知