C++数论刷题记录 Hackerrank Solve Mathematics Sherlock and GCD / Primitive Problem

Sherlock and GCD

Sherlock is stuck while solving a problem: Given an array , he wants to know if there exists a subset  of this array which follows these statements:

  •  is a non-empty subset.
  • There exists no integer  which divides all elements of .
  • There are no elements of  which are equal to another.

Input Format

The first line of input contains an integer, , representing the number of test cases. Then  test cases follow.
Each test case consists of two lines. The first line contains an integer, , representing the size of array . In the second line there are  space-separated integers, , representing the elements of array .

Constraints

Output Format

Print YES if such a subset exists; otherwise, print NO.

Sample Input

3
3
1 2 3
2
2 4
3
5 5 5

Sample Output

YES
NO
NO

 

#include <bits/stdc++.h>

using namespace std;

string ltrim(const string &);
string rtrim(const string &);
vector<string> split(const string &);

// Recursive function to return gcd of a and b
int gcd(int a, int b) {
    if (a == 0)
        return b;
    return gcd(b % a, a);
}
/*
 * Complete the 'solve' function below.
 *
 * The function is expected to return a STRING.
 * The function accepts INTEGER_ARRAY a as parameter.
 */

string solve(vector<int> a) {
    // Sort the vector
    sort(a.begin(), a.end());

    // Move all duplicates to last of vector
    auto it = unique(a.begin(), a.end());

    // Remove all duplicates
    a.erase(it, a.end());
    if(a.size()==1) return "NO";
    else{
        int gcdnow = a[0];
        for(size_t i=1;i<a.size();i++){
            gcdnow = gcd(gcdnow, a[i]);
            
            if(gcdnow==1) return "YES";
        }
        return "NO";
    }   
}

int main()
{
    ofstream fout(getenv("OUTPUT_PATH"));

    string t_temp;
    getline(cin, t_temp);

    int t = stoi(ltrim(rtrim(t_temp)));

    for (int t_itr = 0; t_itr < t; t_itr++) {
        string a_count_temp;
        getline(cin, a_count_temp);

        int a_count = stoi(ltrim(rtrim(a_count_temp)));

        string a_temp_temp;
        getline(cin, a_temp_temp);

        vector<string> a_temp = split(rtrim(a_temp_temp));

        vector<int> a(a_count);

        for (int i = 0; i < a_count; i++) {
            int a_item = stoi(a_temp[i]);

            a[i] = a_item;
        }

        string result = solve(a);

        fout << result << "\n";
    }

    fout.close();

    return 0;
}

string ltrim(const string &str) {
    string s(str);

    s.erase(
        s.begin(),
        find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(isspace)))
    );

    return s;
}

string rtrim(const string &str) {
    string s(str);

    s.erase(
        find_if(s.rbegin(), s.rend(), not1(ptr_fun<int, int>(isspace))).base(),
        s.end()
    );

    return s;
}

vector<string> split(const string &str) {
    vector<string> tokens;

    string::size_type start = 0;
    string::size_type end = 0;

    while ((end = str.find(" ", start)) != string::npos) {
        tokens.push_back(str.substr(start, end - start));

        start = end + 1;
    }

    tokens.push_back(str.substr(start));

    return tokens;
}

 

Primitive Problem

We define a primitive root of prime number  to be some integer  satisfying the property that all values of  where  are different.

For example: if , we want to look at all values of  in the inclusive range from  to . For , the powers of  (where  is in the inclusive range from  to ) are as follows:

Note that each of these evaluates to one of the six distinct integers in the range .

Given prime , find and print the following values as two space-separated integers on a new line:

  1. The smallest primitive root of prime .
  2. The total number of primitive roots of prime .

Need Help? Check out a breakdown of this process at Math Stack Exchange.

Input Format

A single prime integer denoting .

Constraints

Output Format

Print two space-separated integers on a new line, where the first value is the smallest primitive root of  and the second value is the total number of primitive roots of .

Sample Input 0

7

Sample Output 0

3 2

'

#include <bits/stdc++.h>

using namespace std;

string ltrim(const string &);
string rtrim(const string &);

// Function to perform modular exponentiation: (base^exp) % mod
long long mod_exp(long long base, long long exp, long long mod) {
    long long result = 1;
    base = base % mod; // Take base modulo mod
    while (exp > 0) {
        if (exp % 2 == 1) {
            result = (result * base) % mod;
        }
        exp = exp >> 1; // Right shift exp (divide by 2)
        base = (base * base) % mod;
    }
    return result;
}

int gcd(int a, int b) {
    if (a == 0)
        return b;
    return gcd(b % a, a);
}

int phi(unsigned int n) {
    unsigned int result = 1;
    for (unsigned int i = 2; i < n; i++)
        if (gcd(i, n) == 1)
            result++;
    return result;
}

int ord(unsigned int a, unsigned int p) {
    if (a == 0 || p <= 1)
        return -1;
    unsigned int phi_p = p - 1;
    vector<unsigned int> divisors;
    for (unsigned int i = 1; i * i <= phi_p; ++i) {
        if (phi_p % i == 0) {
            divisors.push_back(i);
            if (i != phi_p / i) {
                divisors.push_back(phi_p / i);
            }
        }
    }
    sort(divisors.begin(), divisors.end());
    for (unsigned int d : divisors) {
        if (mod_exp(a, d, p) == 1) {
            return d;
        }
    }
    return -1;
}

int main() {
    string p_temp;
    getline(cin, p_temp);

    int p = stoi(ltrim(rtrim(p_temp)));
    //st
    int smallest = -1;
    for (int a = 1; a < p; ++a) {
        if (ord(a, p) == p - 1) {
            smallest = a;
            break;
        }
    }
    int NumberOfPrim = phi(p - 1);
    cout << smallest << " " << NumberOfPrim;
    return 0;
    
    //end
}

string ltrim(const string &str) {
    string s(str);
    s.erase(
        s.begin(),
        find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(isspace)))
    );
    return s;
}

string rtrim(const string &str) {
    string s(str);
    s.erase(
        find_if(s.rbegin(), s.rend(), not1(ptr_fun<int, int>(isspace))).base(),
        s.end()
    );
    return s;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值