一.背景
補這題,是因爲昨天網絡賽碰到一道素數間隔的題(非常相似,但是作法有差異)
二.重要性質:
①10^9的最大素數間隔爲300
②(p爲素數)
三.思路
這題數據範圍是1e9,而且給出區間是300,根據素數間隔規律,區間裏必有一個素數,只要看該素數的歐拉函數值是否對應即可,有兩種方法:
a.按順序找,直到符合爲止(本代碼方法)
b.找歐拉函數區間裏最大的那個數,那個數一定是素數,同上判斷是否符合。
因爲根據歐拉函數定義,小於n的數中與n互質的數的數目,顯然小範圍內合數歐拉函數比質數小。
b方法見鏈接
四.代碼
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 315;
namespace Miller_Rabin{
ll mul(ll a, ll b, ll p) {
a %= p, b %= p;
ll ans = 0;
while(b) {
if(b & 1) {
ans = ans + a;
if(ans > p) ans -= p;
}
a = a + a;
if(a > p) a -= p;
b >>= 1;
}
return ans;
}
ll qp(ll a, ll b, ll p) {
ll ans = 1; a %= p;
while(b) {
if(b & 1) ans = mul(ans, a, p);
a = mul(a, a, p);
b >>= 1;
}
return ans;
}
bool check(ll a, ll n, ll x, ll t) {
ll ans = qp(a, x, n);
ll last = ans;
for(int i = 1; i <= t; i++) {
ans = mul(ans, ans, n);
if(ans == 1 && last != 1 && last != n - 1) return true;
last = ans;
}
if(ans != 1) return true;
return false;
}
bool go(ll n) {
if(n == 1 || (n & 1) == 0) return false;
if(n == 2) return true;
ll x = n - 1, t = 0;
while((x & 1) == 0) {x >>= 1, ++t;}
srand(time(NULL));
for(int i = 0; i < 8; i++) {
ll a = rand() % (n - 1) + 1;
if(check(a, n, x, t)) return false;
}
return true;
}
}
int T, n;
int a[N];
int getphi(int x) {
int ans = x;
for(int i = 2; 1ll * i * i <= x; i++) {
if(x % i == 0) {
ans = ans / i * (i - 1);
while(x % i == 0) x /= i;
}
}
if(x > 1) ans = ans / x * (x - 1);
return ans;
}
bool gao1() {
int p = -1;
for(int i = 1; i <= n; i++) {
if(Miller_Rabin::go(a[i] + 1)) {
p = a[i] + 2 - i;
int f = 1;
for(int j = 1; j <= n; j++) {
if(a[j] != getphi(p + j - 1)||(a[j]+300-j)>1e9)
//右邊必須加個條件防止跳出範圍
{
f = 0; break;
}
}
if(f) {
cout << p << '\n';
return true;
}
}
}
cout << "yang12138 laji" << '\n';
return false;
}
const int prime[10] = {0, 2, 3, 5, 7, 11, 13};
void gao2() {
int p = -1;
for(int i = 1; i <= 4; i++) {
for(int j = 1; j <= n; j++) {
if(a[j] % (prime[i] - 1)) continue;
int tmp = a[j] / (prime[i] - 1) + 1;
if(Miller_Rabin::go(tmp)) {
p = 1ll * tmp * prime[i] + 1 - j;
int f = 1;
for(int k = 1; k <= n; k++) {
if(a[k] != getphi(k + p - 1)) {
f = 0; break;
}
}
if(f) {
cout << p << '\n';
return;
}
}
}
}
cout << "yang12138 laji" << '\n';
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
//cin >> T;
T=1;
n = 300;
while(T--) {
for(int i = 1; i <= n; i++) cin >> a[i];
bool f = gao1();
//if(!f) gao2();
}
return 0;
}