CF402D Upgrading Array

原题链接

先用素数筛筛下素数,然后考虑贪心去操作。
先求前缀\(GCD\)(求到\(GCD\)\(1\)就不用再往下求了),得到数组\(G[i]\),然后从后往前扫,如果\(f(G[i]) < 0\),那么我们贪心地把\(i\)及之前的数全部除以\(G[i]\),当然前缀\(GCD\)数组同时也要除掉,然后重复上述操作,直到不能除为止。
计算\(f\)可以递归分解求解。

#include<cstdio>
using namespace std;
const int N = 5010;
const int M = 1e6;
int a[N], b[N], pr[M], G[N], l, m;
bool v[M + 10];
inline int re()
{
    int x = 0;
    char c = getchar();
    bool p = 0;
    for (; c < '0' || c > '9'; c = getchar())
        p |= c == '-';
    for (; c >= '0' && c <= '9'; c = getchar())
        x = x * 10 + c - '0';
    return p ? -x : x;
}
int gcd(int x, int y)
{
    if (!y)
        return x;
    return gcd(y, x % y);
}
bool fin(int x)
{
    int l = 1, r = m, mid;
    while (l <= r)
    {
        mid = (l + r) >> 1;
        if (!(b[mid] ^ x))
            return true;
        b[mid] > x ? r = mid - 1 : l = mid + 1;
    }
    return false;
}
int js(int x)
{
    if (!(x ^ 1))
        return 0;
    for (int i = 1; i <= l; i++)
    {
        if (pr[i] * pr[i] > x)
            return fin(x) ? -1 : 1;
        if (!(x % pr[i]))
            return js(x / pr[i]) + (fin(pr[i]) ? -1 : 1);
    }
}
int main()
{
    int i, j, n, la;
    long long s = 0;
    n = re();
    m = re();
    for (i = 1; i <= n; i++)
        a[i] = re();
    for (i = 1; i <= m; i++)
        b[i] = re();
    v[0] = v[1] = 1;
    for (i = 2; i <= M; i++)
    {
        if (!v[i])
            pr[++l] = i;
        for (j = 1; j <= l; j++)
        {
            if (i * pr[j] > M)
                break;
            v[i * pr[j]] = 1;
            if (!(i % pr[j]))
                break;
        }
    }
    G[1] = a[1];
    for (i = 2; i <= n; i++)
    {
        G[i] = gcd(G[i - 1], a[i]);
        if (!(G[i] ^ 1))
            break;
    }
    la = i - 1;
    while(la > 0)
    {
        for (; js(G[la]) >= 0 && la > 0; la--);
        if (la > 0)
            for (i = 1; i <= la; i++)
            {
                a[i] /= G[la];
                G[i] /= G[la];
            }
    }
    for (i = 1; i <= n; i++)
        s += js(a[i]);
    printf("%lld", s);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Iowa-Battleship/p/9878906.html
今日推荐