zoukankan      html  css  js  c++  java
  • P6091 【模板】原根

    给定整数 n,求它的所有原根。

    为了减小你的输出量,给出输出参数 dd,设 nn 的所有原根有 cc 个,从小到大分别为 g_1,\ldots,g_cg1,,gc,你只需要依次输出

     

    int phi[maxn];
    int prime[maxn];   
    int vis[maxn];     
    int rt[maxn];
    ll fac[maxn];
    ll ans[maxn];
    int cnt,num;
    
    int euler_sieve(int n) {
        int cnt = 0;
        for (int i = 2; i <= n; i++) {
            if (!vis[i]) prime[cnt++] = i;
            for (int j = 0; j < cnt; j++) {
                if (i * prime[j] > n) break;
                vis[i * prime[j]] = 1;
                if (i % prime[j] == 0) break;
            }
        }
        return cnt;  
    }
    
    void phi_table(int n) {
        for (int i = 2; i <= n; i++) phi[i] = 0;
        phi[1] = 1;
        for (int i = 2; i <= n; i++) if (!phi[i])
            for (int j = i; j <= n; j += i) {
                if (!phi[j]) phi[j] = j;
                phi[j] = phi[j] / i * (i - 1);
            }
    }
    
    void init(int tot) {
        rt[2] = rt[4] = 1;
        for (int i = 1; i < tot; i++) {
            for (int j = 1; (1ll * j * prime[i]) <= maxn - 10; j *= prime[i]) rt[j * prime[i]] = 1;
            for (int j = 2; (1ll * j * prime[i]) <= maxn - 10; j *= prime[i]) rt[j * prime[i]] = 1;
        }
     }
    
    ll gcd(ll a, ll b) {
        return b == 0 ? a : gcd(b, a % b);
    }
    
    ll quickPower(ll a, ll b, ll m) {
        ll res = 1;
        ll base = a;
        while (b) {
            if (b & 1) {
                res *= base;
                res %= m;
            }
            base *= base;
            base %= m;
            b >>= 1;
        }
        return res;
    }
    
    
    void get_fac(int p) {
        for (int i = 2; i * i <= p; i++) {
            if (p % i == 0) {
                fac[++cnt] = i;
                while (p % i == 0) p /= i;
            }
        }
        if (p > 1) fac[++cnt] = p;
    }
    
    bool check ( ll x, ll p ) {
        if (quickPower(x, phi[p], p) != 1) return 0;
        for (int i = 1; i <= cnt; i++) {
            if (quickPower(x, phi[p] / fac[i], p) == 1) return 0;
        }
        return 1;
    }
    
    int find_rt(ll p) {
        for (int i = 1; i < p; i++) if (check(i, p)) return i;
        return 0;
    }
    
    void get_rt(ll p, ll x) {
        int prod = 1;
        for (int i = 1; i <= phi[p]; i++) {
            prod = (1ll * prod * x) % p;
            if (gcd(i, phi[p]) == 1) ans[++num] = prod;
        }
    }
    
    int main() {
        int tot = euler_sieve(maxn);
        phi_table(maxn);
        init(tot);
        int T;
        ll n, d;
        scanf("%d", &T);
        while (T--) {
            scanf("%lld%lld", &n, &d);
            if (rt[n]) {
                cnt = num = 0;
                get_fac(phi[n]);
                ll mm = find_rt(n);
                get_rt(n, mm);
                sort(ans + 1, ans + num + 1);
                printf("%d\n", num);
                for (int i = 1; i <= num / d; i++) printf("%d ", ans[i * d]);
                puts("");
            }
            else puts("0\n");
        }
    }
  • 相关阅读:
    洛谷 P2480 [SDOI2010]古代猪文
    [六省联考2017]组合数问题
    数据结构--左偏树(可并堆)
    图论--tarjan求割点
    图论--tarjan缩点
    图论--DFS-SPFA求负环
    图论--tarjan求lca
    洛谷 P2163 [SHOI2007]Tree 园丁的烦恼
    数据结构--主席树(不带修改)
    洛谷 P1712 区间
  • 原文地址:https://www.cnblogs.com/hznumqf/p/12909696.html
Copyright © 2011-2022 走看看