codeforces 402 D. Upgrading Array(数论+贪心)

题目链接:http://codeforces.com/contest/402/problem/D

题意:给出一个a串和素数串b 。f(1) = 0; p为s的最小素因子如果p不属于b , 否则 .

a串还可以进行这样的操作找一个r使得(1<=r<=n)g=gcd(a[1],a[2]......a[r]),然后再是a[1~r]/g。

题解:其实f的求和可以理解为num1(好的素因子)-num2(不好的素因子)。

然后就是对a操作的理解,a怎么样才需要进行这样的操作呢?只要g中不好的素因子大于好的素因子那么,

删掉这样的g就能增加f的总和。还有求除最小素因数的方法

for(int j = 2 ; j * j <= x ; j++) {//这个是快速的求法,为什么这么求可以自行理解

            if(!prime[j])//prime表示是否是素数与处理一下

                continue;

            if(x % j)

                continue;

            bool flag = mmp[j];//定义map的mmp来判断j是否是坏素因数

            while(x % j == 0) {

                x /= j;

                if(flag)

                    ans--;

                else

                    ans++;

            }

        }

if(x > 1) {

            if(mmp[x])

                ans--;

            else

                ans++;

        }

#include <iostream>
#include <cmath>
#include <cstdio>
#include <map>
#define inf 0X3f3f3f3f
using namespace std;
const int M = 1e5 + 10;
int a[5010] , b[5010];
int prime[M];
map<int , bool>mmp;
void IsPrime(){
    prime[0] = prime[1] = 0;
    prime[2] = 1;
    for(int i = 3 ; i < M ; i++)
        prime[i] = i % 2 == 0 ? 0 : 1;
    int t = (int)sqrt(M * 1.0);
    for(int i = 3 ; i <= t ; i++)
        if(prime[i])
            for(int j = i * i ; j < M ; j += 2 * i)
                prime[j] = 0;
}
int gcd(int x , int y) {
    return (y > 0) ? gcd(y , x % y) : x;
}
int main() {
    int n , m;
    scanf("%d%d" , &n , &m);
    mmp.clear();
    IsPrime();
    for(int i = 0 ; i < n ; i++) {
        scanf("%d" , &a[i]);
    }
    for(int i = 0 ; i < m ; i++) {
        scanf("%d" , &b[i]);
        mmp[b[i]] = true;
    }
    for(int i = n - 1 ; i >= 0 ; i--) {
        int x = 0;
        for(int j = 0 ; j <= i ; j++) {
            x = gcd(x , a[j]);
        }
        int bad = 0 , good = 0;
        int xx = x;
        for(int l = 2 ; l * l <= x ; l++) {
            if(!prime[l])
                continue;
            if(x % l)
                continue;
            bool flag = mmp[l];
            while(x % l == 0) {
                x /= l;
                if(flag)
                    bad++;
                else
                    good++;
            }
        }
        if(x > 1) {
            if(mmp[x])
                bad++;
            else
                good++;
        }
        if(bad > good) {
            for(int j = 0 ; j <= i ; j++) {
                a[j] /= xx;
            }
        }
    }
    int ans = 0;
    for(int i = 0 ; i < n ; i++) {
        int x = a[i];
        for(int j = 2 ; j * j <= x ; j++) {
            if(!prime[j])
                continue;
            if(x % j)
                continue;
            bool flag = mmp[j];
            while(x % j == 0) {
                x /= j;
                if(flag)
                    ans--;
                else
                    ans++;
            }
        }
        if(x > 1) {
            if(mmp[x])
                ans--;
            else
                ans++;
        }
    }
    printf("%d
" , ans);
    return 0;
}
原文地址:https://www.cnblogs.com/TnT2333333/p/6759819.html