cf Mahmoud and Ehab and another array construction task(素数处理大乱炖)

做惯了素数分解,其实直接因数分解,复杂度也是根号的,这非常有用.
筛是线性的,这也非常重要.
给出一段数,让你给出一个字典序大于他的最小数列.这种最小的大于..不是特别的东西.
每一个数放进来,素因数分解,如果和之前数没有重合,那么把他的新素因数都过一遍.
如果有了重合,那么就不行了.
这题说不出什么,感觉就是筛法的重现.搞不太清楚.

#include <iostream>
#include <cmath>
#include <cstring>
#include <vector>
using namespace std;
#define debug(x) //std::cerr << #x << " = " << (x) << std::endl
typedef long long LL;
const int MAXN = 5e6+17;
int a[MAXN],b[MAXN],vis[MAXN],visr[MAXN];
int prime[1100000],primesize=0;
bool isprime[11000000];
void sieve(int listsize){
    memset(isprime, 1, sizeof(isprime));
    isprime[1] = false;
    for(int i=2;i<=listsize;i++){
        if(isprime[i]) prime[++primesize]=i;
         for(int j = 1; j <= primesize && i*prime[j] <= listsize;j++){
            isprime[i*prime[j]] = false;
            if(i%prime[j] == 0) break;
         }
    }
}
vector<int > dap(int x)
{
    vector<int > vec;
    int rt = sqrt(x);
    if(isprime[x])
    {
        vec.push_back(x);
        return vec;
    }
    for(int j=1;j<primesize;++j)
    {
        int p = prime[j];
        if(p>rt) break;
        if(x%p==0)
            vec.push_back(p);
        while(x%p==0)
            x/=p;
    }
    if(x>1)
        vec.push_back(x);
    return vec;
}
int main(int argc ,char const *argv[])
{
    #ifdef noob
    freopen("Input.txt","r",stdin);freopen("Output.txt","w",stdout);
    #endif
    sieve(200017);
    int n;
    cin>>n;
    for(int i=0;i<n;++i)
        cin>>a[i];
    int sup = 1;
    bool have = false;
    for(int i=0;i<n;++i)
    {
        if(have)
        {
            for(int j = sup+1;;++j)
            {
                if(!visr[j])
                {
                    sup = j;
                    break;
                }
            }
            vector<int > zt = dap(sup);
            for(auto j : zt)
            {
                for(int k = j;k<=5e6;k+=j)
                    visr[k] = 1;
            }
            b[i] = sup;
            continue;
        }
        vector<int > now = dap(a[i]);
        debug(a[i]);
        for(auto j : now)
        {
            if(vis[j]) 
                have = true;
            debug(j);
        }
        if(have)
        {
            int tmp;
            for(int j = a[i]+1;;++j)
            {
                if(!visr[j])
                {
                    tmp = j;
                    break;
                }
            }
            vector<int > zt = dap(tmp);
            for(auto j : zt)
            {
                for(int k = j;k<=5e6;k+=j)
                    visr[k] = 1;
            }
            b[i] = tmp;
        }
        else
        {
            for(auto j : now)
            {
                for(int k = j;k<=5e6;k+=j)
                    visr[k] = 1;
                vis[j] = 1;
            }
            b[i] = a[i];
        }
        debug(b[i]);
    }
    for(int i=0;i<n;++i)
        cout<<b[i]<<endl;
    return 0;   
}

猜你喜欢

转载自blog.csdn.net/m0_37802215/article/details/79874729