2018南京icpc-J-Prime Game (欧拉筛+唯一分解定理)

题意:给定n个数ai(n<=1e6,ai<=1e6),定义,并且fac(l,r)为mul(l,r)的不同质因数的个数,求

思路:可以先用欧拉筛求出1e6以内的所有质数,然后对所有ai判断,如果ai不是质数就利用唯一分解定理计算其所有质因数。然后按照顺序依次计算每个质因子的贡献。假设n=5,对质因子2,依次记录它在数组出现的下标,如果它在2、4下标出现了,那么它的贡献即为所有包含2或4的区间个数,逆向计算,即所有区间个数-不包含2和4的区间个数,即

n(n+1)/2-m1(m1+1)/2-m2(m2+1)/2-m3(m3+1)/2,其中m1=2-1-0=1,m2=3-2=1,m3=5-4=1,即3块不包含2和4的子区间长度。

AC代码:

#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;

typedef long long LL;
const int maxn=1e6+5;
int n,a[maxn],cnt,vis[maxn],prime[maxn];
int pre[maxn],vis1[maxn];
LL ans,cs;

void Eular(){
    for(int i=2;i<maxn;++i){
        if(!vis[i]) prime[cnt++]=i;
        for(int j=0;j<cnt&&i*prime[j]<maxn;++j){
            vis[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
}

void solve(int id,int x){
    if(!vis1[x]){
        vis1[x]=1;
        ans+=cs;
    }
    LL t=id-1-pre[x];
    pre[x]=id;
    ans-=1LL*t*(t+1)/2;
}

int main(){
    Eular();
    scanf("%d",&n);
    cs=1LL*n*(n+1)/2;
    for(int i=1;i<=n;++i)
        scanf("%d",&a[i]);
    for(int i=1;i<=n;++i){
        if(a[i]==1) continue;
        if(!vis[a[i]]){
            solve(i,a[i]);
        }
        else{
            int tmp=a[i];
            for(int j=2;j*j<=tmp;++j){
                if(tmp%j==0){
                    while(tmp%j==0) tmp/=j;
                    solve(i,j);
                }
            }
            if(tmp!=1){
                solve(i,tmp);
            }
        }
    }
    for(int i=0;i<cnt;++i){
        int t=pre[prime[i]];
        if(t){
            t=n-t;
            ans-=1LL*t*(t+1)/2;
        }
    }
    printf("%lld\n",ans);
}

原文地址:https://www.cnblogs.com/FrankChen831X/p/11769741.html

时间: 2024-07-30 14:57:52

2018南京icpc-J-Prime Game (欧拉筛+唯一分解定理)的相关文章

hdu2421-Deciphering Password-(欧拉筛+唯一分解定理+积性函数+立方求和公式)

Deciphering Password Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2357    Accepted Submission(s): 670 Problem Description Xiaoming has just come up with a new way for encryption, by calculati

hdu3826-Squarefree number-(欧拉筛+唯一分解定理)

Squarefree number Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3691    Accepted Submission(s): 971 Problem Description In mathematics, a squarefree number is one which is divisible by no per

hdu4497-GCD and LCM-(欧拉筛+唯一分解定理+组合数)

GCD and LCM Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 3409    Accepted Submission(s): 1503 Problem Description Given two positive integers G and L, could you tell me how many solutions of

欧拉筛 线性筛 素数+莫比乌斯的mu[]

https://blog.csdn.net/qq_39763472/article/details/82428602 模板来自https://blog.csdn.net/Avalon_cc/article/details/81663214 bool isP[N]; int P[N], ind; void Euler() { mem(isP,1); mu[1]=1; ind=0; for(int i=2;i<N;i++) { if(isP[i]) P[ind++]=i, mu[i]=-1; for

素数筛&amp;&amp;欧拉筛 BZOJ2818 Gcd BZOJ2190 [SDOI2008]仪仗队

折腾了一晚上很水的数论,整个人都萌萌哒 主要看了欧拉筛和素数筛的O(n)的算法 这个比那个一长串英文名的算法的优势在于没有多次计算一个数,也就是说一个数只筛了一次,主要是在%==0之后跳出实现的,具体的解释看的迷迷糊糊,特别是欧拉函数的求解 http://blog.csdn.net/lerenceray/article/details/12420725 代码如下 1 void ES(){ 2 for(int i=2;i<n;i++){ 3 if (!pd[i]){ 4 prime[++top]=

常见模板(欧拉筛素数,最小生成树,快排,并查集,单源最短路)

欧拉筛素数: #include<cstdio> #define maxn 10000000+10 using namespace std; int n,prime[5000001],num_prime=0,m; bool if_prime[maxn]; void euler(int limit) { for(int i=2;i<=limit;i++) { if(!if_prime[i]) prime[++num_prime]=i; for(int j=1;prime[j]*i<=l

欧拉筛(线性筛)

素数筛,就是按照顺序把合数踢掉,剩下的是素数. 欧拉筛是一种O(n)求素数的筛法.他避免了埃拉特斯特尼筛法对同一数的多次筛除. 欧拉筛的原理是只通过数的最小质因数筛数. 先上代码: #include <cstdio> using namespace std; const int maxn=10000000; int n, m, prime[maxn], isnt_prime[maxn], tot; void get_prime(int n){ isnt_prime[0]=isnt_prime[

[51NOD1181]质数中的质数(质数筛法)(欧拉筛)

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1181 思路:欧拉筛出所有素数和一个数的判定,找到大于n的最小质数序号p,并且判断p是不是质数,输出这个数. 1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛┃\○/ 5 ┓┏┓┏┓┃ / 6 ┛┗┛┗┛┃ノ) 7 ┓┏┓┏┓┃ 8 ┛┗┛┗┛┃ 9 ┓┏┓┏┓┃ 10 ┛┗┛┗┛┃ 11 ┓┏┓┏┓┃ 12

【BZOJ 2190】【SDOI 2008】仪仗队 欧拉筛

欧拉筛模板题 #include<cstdio> using namespace std; const int N=40003; int num=0,prime[N],phi[N]; bool notp[N]; inline void shai(int n){ phi[1]=1; for(int i=2;i<=n;++i){ if (!notp[i]){ prime[++num]=i; phi[i]=i-1; } for(int j=1;j<=num&&i*prime