Codeforces 912E - Prime Gift

传送门:http://codeforces.com/contest/912/problem/E

有整数集上的映射G:S→T。其中S为一个质数集;T为一个整数集:其中,每一个数的所有质因子均为S中的元素。现给定一个n元的质数集S,求T=G(S)中的第k小的整数。

首先考虑集合T=G(S)的构造:

设质数集S={pi|i=1,2,...,n},则$T=G(S)=\{\prod_{i=1}^{n}{p_i^{a_i}}|a_i=0,1,2,\cdots;i=1,2,\cdots,n\}$。

集合T=G(S)可以通过DFS构造,这里用std::vector实现:

void dfs(int idx, int64_t cur)
{
    if (idx == s.size()) {
        gs.push_back(cur);
        return;
    }
    if (s[idx] <= inf / cur)
        dfs(idx, cur * s[idx]);
    dfs(idx + 1, cur);
}

考虑将S划分成两个集合AB,划分满足:AB=SAB=Ø,则G(A)∩G(B)=Ø。划分的方式可以是按照下标的奇偶性划分,即A={pi|i=1,3,...;i≤n},B={pi|i=2,4,...;i≤n}。于是,占用空间由|G(S)|,降至|G(A)|+|G(B)|。同理,可以通过DFS构造集合G(A)、G(B)。

order(x)返回x在集合T中的“序号”k:若集合T中第k小的数为tk,则tk≤x<tk+1。可以在O(|G(A)|+|G(B)|)的时间复杂度下实现这个函数。

之后,在0~inf上查找。采用二分查找法。查找的时间复杂度为O((|G(A)|+|G(B)|)·log inf)。

参考程序如下:

#include <bits/stdc++.h>
using namespace std;

const int64_t inf = (int64_t)1e18;
vector<int64_t> a[2], g[2];

void dfs(int obj, int idx, int64_t cur)
{
    if (idx == a[obj].size()) {
        g[obj].push_back(cur);
        return;
    }
    if (a[obj][idx] <= inf / cur)
        dfs(obj, idx, cur * a[obj][idx]);
    dfs(obj, idx + 1, cur);
}

int order(int64_t x)
{
    int res = 0;
    int i = g[0].size() - 1, j = 0;
    for (; i >= 0; i--) {
        for (; j < g[1].size() && g[1][j] <= x / g[0][i]; j++);
        res += j;
    }
    return res;
}

int main(void)
{
    int n, k;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        int p;
        scanf("%d", &p);
        a[i & 1].push_back(p);
    }
    scanf("%d", &k);
    //generate sequences g-s.
    dfs(0, 0, 1LL);
    sort(g[0].begin(), g[0].end());
    dfs(1, 0, 1LL);
    sort(g[1].begin(), g[1].end());
    //binary search.
    int64_t low = 0LL;
    int64_t high = inf;
    while (low <= high) {
        int64_t mid = (low + high) / 2;
        int ord = order(mid);
        if (ord < k) low = mid + 1;
        else high = mid - 1;
    }
    printf("%I64d\n", low);
    return 0;
}

 

posted on 2018-01-07 21:41  SiuGinHung  阅读(375)  评论(0编辑  收藏  举报

导航