XVIII Open Cup named after E.V. Pankratiev Problem 9. Primitive divisors 数论

Victor, a top coder, loves the Internet. Every day he registers on many new websites, and every
time he is asked to think of a new password. Victor wrote a password generator, which produces
a new password when given a prime number. All he has to do now is to learn how to generate
various prime numbers.
Victor has a favorite number q. To obtain the prime numbers, he decided to use prime divisors
of q
n − 1, increasing the exponent n daily. However, to get rid of duplicate prime numbers, he
chooses on the n-th day only those numbers which he has not encountered earlier, i.e. those that
were not the prime divisors of q
m − 1 for each m < n.
Help our coder to write a program that finds acceptable prime divisors for the given q and n.
Since Victor’s password generator only accepts relatively small numbers, he needs prime numbers
not greater than 107
.
Input
The only line of the input file contain two integers q and n (2 ≤ q ≤ 109
, 1 ≤ n ≤ 109
).
Output
The first line of the output file must contain the number of the desired divisors of the number q
n−1.
The second line must contain these divisors in ascending order, separated by space characters. All
these numbers must be prime, not greater than 107 and must not occur for the lower values of n.
Example
input.txt output.txt
3 4 1
5
2 6 0
Example explanation
In the first example q
n − 1 = 80 = 24
· 5. The numbers 2 and 5 are thus prime divisors. However,
2 divides 3
1 − 1, and 5 does not divide the numbers 3
1 − 1, 3
2 − 1 and 3
3 − 1, so Victor can take
only one prime divisor — the number 5. In the second example, 2
6 − 1 = 63 = 32
· 7. No prime
divisor fits, because 3 divides 2
2 − 1, and 7 divides 2
3 − 1.

思路: 题目说 素数 <= 1e7 ,那么我们枚举每一个素数,看是否满足 q^n mod p ==1, 如果满足,那么我们反解这个同余方程

由引理:
若 a,n 互质,那么满足 a^x ≡ 1 ( mod n ) 最小正整数 x0 为 φ ( n ) 的因数,

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<string>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
typedef long long ll;
using namespace std;
typedef unsigned long long int ull;
#define maxn 20000005
#define ms(x) memset(x,0,sizeof(x))
#define Inf 0x7fffffff
#define inf 0x3f3f3f3f
const ll  mod = 1e9 + 7;
#define pi acos(-1.0)
#define pii pair<int,int>
#define eps 1e-5
#define pll pair<ll,ll>
#define lson 2*x
#define rson 2*x+1
//const ll maxn= 1005;

long long  qupower(ll a, ll b,ll mod) {
    long long  ans = 1;
    while (b) {
        if (b & 1)ans = ans * a%mod;
        b >>= 1;
        a = a * a%mod;
    }
    return ans;
}

inline int read() {
    int an = 0, x = 1; char c = getchar();
    while (c > '9' || c < '0') {
        if (c == '-') {
            x = -1; 
        }
        c = getchar();
    }
    while (c >= '0'&&c <= '9') {
        an = an * 10 + c - '0'; c = getchar();
    }
    return an * x;
}


const int N = 10000000;
int v[maxn], prime[maxn];
int res[maxn];
int tot;
int m;
int n, q;


bool judge(int x) {
    if (x <= n)return false;
    if (qupower(q, n, x) != 1)return false;
    int cur = x - 1;
    int tmp = x - 1;
    while (tmp > 1) {
        int sy = v[tmp];
        if (qupower(q, cur / sy, x) == 1)cur = cur / sy;
        if (n > cur)return false;
        tmp = tmp / sy;
    }
    return true;
}


int main() {
    ios::sync_with_stdio(false);
//  freopen("input.txt", "r", stdin);
//  freopen("output.txt", "w", stdout);
    cin >> q >> n;
    for (int i = 2; i < N; i++) {
        if (!v[i]) {
            v[i] = i;
            prime[tot++] = i;
        }
        for (int j = 0; j < tot&&i*prime[j] < N; j++) {
            v[i*prime[j]] = prime[j];
            if (i%prime[j] == 0)break;
        }
    }
    int cnt = 0;
    for (int i = 0; i < tot; i++) {
        if (judge(prime[i]))res[++cnt] = prime[i];
    }
    cout << cnt << endl;
    for (int i = 1; i <= cnt; i++)cout << res[i] << ' ';

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值