CF_402D Upgrading Array 因式分解

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

/**算法分析:

*/
#include<bits/stdc++.h>
#define MAXN 5005
#define MAXM 110000
#define PI acos(-1.0)
#define REP(i,n) for(int i=0; i<n; i++)
#define FOR(i,s,t) for(int i=s; i<=t; i++)
#define mem(a,b)  memset(a,b,sizeof(a))
#define show(x) { cerr<<">>>"<<#x<<" = "<<x<<endl; }
#define showtwo(x,y) { cerr<<">>>"<<#x<<"="<<x<<"  "<<#y<<" = "<<y<<endl; }
using namespace std;

int prime[MAXM],prime_index;
int a[MAXN],gcd[MAXN];
int n,m;
set<int> badset;
map<int,int> vis;

void get_prime()
{
    prime_index = 0;
    bool flag[MAXM]; mem(flag,0);
    FOR(i,2,MAXM-1)
    {
        if(!flag[i])
        {
            prime[prime_index++] = i;
            for(int j=i+i; j<MAXM; j+=i)
                flag[j] = true;
        }
    }
}

int F(int s)
{
    int ret = 0,rcd = s;  //这个rcd十分重要,注意改变的数如果还要操作就需要记录
    if(badset.count(s)) return -1;
    if(vis.find(s) != vis.end()) return vis[s];
    //进行因式分解,一种预处理出质数,另一种直接sqrt(n);
 /**
    for(int i=0; i < prime_index && prime[i]*prime[i] <= s; i++)
    {
        int p = prime[i];
        if(s % p == 0)
        {
            int isbad;
            if(badset.count(p)) isbad = -1;
            else                isbad = 1;
            while(s % p == 0) ret += isbad, s /= p;
        }
    }
    */
    for(int i=2; i*i <= s; i++)
    {
        int p = i;
        if(s % p == 0)
        {
            int isbad;
            if(badset.count(p)) isbad = -1;
            else                isbad = 1;
            while(s % p == 0) ret += isbad, s /= p;
        }
    }

    if(s != 1)
    {
        if(badset.count(s)) ret--;
        else                ret++;
    }
    return vis[rcd] = ret;
}

int main()
{
   // freopen("E:\acm\input.txt","r",stdin);
   // get_prime();
    cin>>n>>m;
    FOR(i,1,n) scanf("%d",&a[i]);
    FOR(i,1,m)
    {
        int tmp; scanf("%d",&tmp);
        badset.insert(tmp);
    }
    int ans = 0;
    gcd[0] = a[1];
    FOR(i,1,n)
    {
        ans += F(a[i]);
        gcd[i] = __gcd(gcd[i-1],a[i]);
    }

    int decr = 0;
    for(int i=n; i>=1; i--)
    {
        int cur_f = F(gcd[i]) + decr;
        if(cur_f < 0)
        {
            ans -= cur_f * i;
            decr -= cur_f;
        }
    }
    cout<<ans<<endl;
}
View Code
原文地址:https://www.cnblogs.com/acmdeweilai/p/3616635.html