zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 37 G. List Of Integers (二分,容斥定律,数论)

    G. List Of Integers

    time limit per test

    5 seconds

    memory limit per test

    256 megabytes

    input

    standard input

    output

    standard output

    Let's denote as L(x, p) an infinite sequence of integers y such that gcd(p, y) = 1 and y > x (where gcd is the greatest common divisor of two integer numbers), sorted in ascending order. The elements of L(x, p) are 1-indexed; for example, 9, 13 and 15 are the first, the second and the third elements of L(7, 22), respectively.

    You have to process t queries. Each query is denoted by three integers x, p and k, and the answer to this query is k-th element of L(x, p).

    Input

    The first line contains one integer t (1 ≤ t ≤ 30000) — the number of queries to process.

    Then t lines follow. i-th line contains three integers x, p and k for i-th query (1 ≤ x, p, k ≤ 106).

    Output

    Print t integers, where i-th integer is the answer to i-th query.

    Examples

    input

    Copy

    37 22 17 22 27 22 3
    

    output

    Copy

    91315
    

    input

    Copy

    542 42 4243 43 4344 44 4445 45 4546 46 46
    

    output

    Copy

    18787139128141
    

    题目链接:

    https://codeforces.com/contest/920/problem/G

    题意:

    有t组询问,对于每一组询问,

    给你三个整数x,p,k

    问有在大于x的整数中,与p互质的第k小的数y是哪个?

    思路:

    对于每一组询问我们在区间([x+1,1e9]) 这个区间内,二分答案y

    同时容斥定律可以求得区间([l,r]) 中与一个数num互质的数个数。——知识点[1]

    那么我们可以求区间([x+1,y])中与p互质的数个数与k比较,然后进行转移区间即可。

    先筛出(1e6) 内的所有质数,然后(log(p)) 的时间复杂度去唯一分解询问中的p,然后二进制枚举+容斥定律辅助二分即可。

    不会的话,建议先学一下知识点1,再来解决本题。

    code:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define sz(a) int(a.size())
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
    #define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
    #define du2(a,b) scanf("%d %d",&(a),&(b))
    #define du1(a) scanf("%d",&(a));
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) {a %= MOD; if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
    void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("
    ");}}}
    
    inline void getInt(int *p);
    const int maxn = 1000010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    // const int maxn = 1e7 + 50;
    bool noprime[maxn + 50];
    vector <int> p;
    int getPrime()
    {
        // 华丽的初始化
        memset(noprime, false, sizeof(noprime));
        p.clear();
    
        int m = (int)sqrt(maxn + 0.5);
        // 优化的埃筛
        for (int i = 2; i <= m; i++) {
            if (!noprime[i]) {
                for (int j = i * i; j <= maxn; j += i) {
                    noprime[j] = true;
                }
            }
        }
        // 把素数加到vector里
        for (int i = 2; i <= maxn; i++) {
            if (!noprime[i]) {
                p.push_back(i);
            }
        }
        //返回vector的大小
        return p.size();
    
    }
    std::vector<ll> v;
    void breakdown(ll n, ll len)
    {
        int pos = 0;
        for (int i = 0; 1ll * p[i]*p[i] <= n && i < len; i++) {
            if ( n % p[i] == 0) {
                v.push_back(p[i]);
                while (n % p[i] == 0) {
                    n /= p[i];
                }
            }
        }
        if ( n > 1) {
            v.push_back(n);
        }
    
    }
    int x, pw, k;
    int len ;
    ll solve(ll l, ll r)
    {
        int maxstate = (1 << len) - 1;
        ll ans = 0ll;
        l--;
        for (int i = 0; i <= maxstate; ++i) {
            int num = 0;
            ll p = 1ll;
            for (int j = 0; j < len; ++j) {
                if (i & (1 << j)) {
                    num++;
                    p *= v[j];
                }
            }
            ans += (r / p - l / p) * ((num & 1) ? -1ll : 1ll);
        }
        return ans;
    }
    int main()
    {
        //freopen("D:\code\text\input.txt","r",stdin);
        //freopen("D:\code\text\output.txt","w",stdout);
        int n;
        int w = getPrime();
        du1(n);
        while (n--) {
            du3(x, pw, k);
            v.clear();
            breakdown(pw, w);
            len = sz(v);
            ll l = x + 1ll;
            ll r = 1e8;
            ll mid;
            ll ans;
            while (l <= r) {
                mid = (l + r) >> 1;
                if (solve(x + 1ll, mid) >= k) {
                    ans = mid;
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            }
            printf("%lld
    ", ans );
        }
        return 0;
    }
    inline void getInt(int *p)
    {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        } else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    
    
    
    
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    事务传播机制,搞懂。
    洛谷 P1553 数字反转(升级版) 题解
    洛谷 P1200 [USACO1.1]你的飞碟在这儿Your Ride Is Here 题解
    洛谷 P1055 ISBN号码 题解
    洛谷 P2141 珠心算测验 题解
    洛谷 P1047 校门外的树 题解
    洛谷 P1980 计数问题 题解
    洛谷 P1008 三连击 题解
    HDU 1013 题解
    HDU 1012 题解
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/11617911.html
Copyright © 2011-2022 走看看