2022年第三届辽宁省大学生程序设计竞赛:F-互质

328 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情

2022年第三届辽宁省大学生程序设计竞赛——F-互质

F-互质

题目描述

琴·古恩希尔德,蒙德城西风骑士团代理团长,四风守护中的南风之狮。身为西风骑士团的代理团长,琴一直忠于职守,为人们带来安宁。虽然并非天赋异禀,但通过刻苦训练,如今的她已然能够独当一面。当风魔龙的威胁开始临近,这位可靠的代理团长早已做好了准备,誓要守护蒙德。

雷泽,住在蒙德地区奔狼领,远离城市与人群,和狼一同生活的少年。直觉锐利,身姿迅捷。

琴团长这几天准备教一下雷泽数学,问了雷泽一个关于互质的问题。

互质是一个数学概念,两个数互质是指两个数的共同因子只有1。

琴团长提出了T次询问,每次询问给出一个正整数n,询问雷泽是否存在一个正整数x,满足x大于等于n/4向上取整,小于等于n/2向下取整,且x与n互质。

雷泽并不会数学,于是便向你求助。

输入描述:

第一行只有一个正整数T,表示询问的数量。 接下来的T行,每行一个正整数n,表示询问的数字。
​
​
1 <= T <= 10^64 <= n <= 10^16

输出描述:

本题采用special judge。
​
​
 输出一共T行,每次询问分别输出一个整数,如果存在一个满足上述条件的x,输出这个x,否则输出-1。               

输入

2
6
9

输出

-1
4

问题解析

一开始想筛出全部的质数,然后根据区间{n/4,n/2}来二分找在区间中的质数,但是后来发现n太大了,而且质数也不一定就是正确答案,正确答案还有可能是非质数。

后面又想出,当n很小时,区间{n/4,n/2}不会太大,我们可以直接枚举里面的元素i,当gcd(i,n)==1时,i就是答案。

但当n很大时,我们显然不能这么玩,因为n很大时,区间{n/4,n/2}也会很大,比如当n是4e15时,区间就是{1e15,2e15},如果枚举,我们要枚举1e15个数。

但是,很明显不会有很长的一段连续数都不与n互质。因为一般来说连续100个数左右肯定会有质数的出现,那么我们不用傻乎乎的枚举到从n/4枚举到n/2。我们枚举n/4到n/4+100就行。

(100要是觉得多了,50也可以)

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include <random>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<fstream>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#include<bitset>#pragma GCC optimize(2)
#pragma GCC optimize(3)#define endl '\n'
#define int ll
#define PI acos(-1)
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 1e6 + 50, MOD = 1e9 + 7;
​
void solve()
{
    int n;
    cin >> n;
    int l = n / 4, r = n / 2;
    if (n % 4 != 0)l++;
    for (int i = l; i <= min(r, l + 100); i++)
    {
        if (gcd(i, n) == 1)
        {
            cout << i << endl;
            return;
        }
    }
    cout << -1 << endl;
}
​
signed main()
{
​
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int t = 1;
    cin >> t;
​
    while (t--)
    {
        solve();
    }
    return 0;
}