zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    pandas DataFrame(5)-合并DataFrame与Series
    pandas Series的sort_values()方法
    np.corrcoef()方法计算数据皮尔逊积矩相关系数(Pearson's r)
    switch case 多个处理方式涉及到销售优惠折扣方案处理
    标量函数取规则名称
    调用企业微信接口发送消息
    C#中NameValueCollection类用法 读取配置信息
    .NET Datable分解数据表
    触发器批量业务操作实现方式 update触发器用游标处理
    Lamda OrderBy 排序问题
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/6759819.html
Copyright © 2011-2022 走看看