分解质因数(线性筛)

Posted dongdong25800

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分解质因数(线性筛)相关的知识,希望对你有一定的参考价值。

 

https://ac.nowcoder.com/acm/contest/923/B

我真是个辣鸡,现在才知道线性筛,

思路:对于每个数字的阶乘,开一个一维数组记录每个数字出现的个数,先利用一维差分将每个数字的阶乘中出现都得数字累加个数,然后再利用线性筛中,已知每个数字的最小质因数是什么,在比较过程中,我们可以从大到小比较,如果发现对于同一个数字它的出现次数不同,我们可以把这个数字划分为两个数字的乘积形式(已知每个数字的最小质因数都是固定的),如果数字相同就不用管了,最后在遍历一遍看看是否每个位置的数字个数都相同就可以了。

 

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int v[maxn],prime[maxn];
int a[maxn],b[maxn];
int da[maxn],db[maxn];
void primes(int n)

    memset(v,0,sizeof(v));
    int m=0;
    for(int i=2; i<=n; i++)
    
        if(v[i]==0)
        
            v[i]=i;
            prime[++m]=i;
        
        for(int j=1; j<=m; j++)
        
            if(prime[j]>v[i]||prime[j]>n/i) break;
            v[i*prime[j]]=prime[j];
        
    

int main()

    primes(100000);
    int t;
    scanf("%d",&t);
    for(int it=1; it<=t; it++)
    
        int n,m;
        scanf("%d%d",&n,&m);
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(da,0,sizeof(da));
        memset(db,0,sizeof(db));

        for(int i=1; i<=n; i++)
        
            int t;
            scanf("%d",&t);
            if(t>1)
            
                da[2]++;
                da[t+1]--;
            
        
        for(int i=1; i<=m; i++)
        
            int t;
            scanf("%d",&t);
            if(t>1)
            
                db[2]++;
                db[t+1]--;
            
        
        for(int i=2; i<=1e5; i++)
        
            da[i]+=da[i-1];
            db[i]+=db[i-1];
            a[i]+=da[i];
            b[i]+=db[i];
        
        for(int i=1e5; i>=2; i--)
        
            if(a[i]!=b[i])
            
                int zy1=i/v[i];
                int zy2=i/zy1;
                int ta=a[i];
                int tb=b[i];
                a[i]=b[i]=0;
                a[zy1]+=ta;
                a[zy2]+=ta;
                b[zy1]+=tb;
                b[zy2]+=tb;
            
        
        int flag=1;
        for(int i=2; i<=1e5; i++)
        
            if(a[i]!=b[i])
            
//            printf("%d %d\n",a[i],b[i]);
                flag=0;
                break;
            
        
        if(flag)
            printf("equal\n");
        else
            printf("unequal\n");
    

 

以上是关于分解质因数(线性筛)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 893E Counting Arrays:dp + 线性筛 + 分解质因数 + 组合数结论

质因数分解总结

算法竞赛模板(数论)

质因数分解

AcWing - 197 - 阶乘分解

质数筛与质因数分解