【刷题记录】 Gym-101981J Prime Game 素数筛+思维

目录

一. 问题描述

二. 题解代码


一. 问题描述

Problem Description

给出n个数字的序列,求表达式:

其中fac(i,j)是指区间[i,j]内数字乘积的素数因子的个数(重复算一个)。

二. 题解代码

        因为1<=n<=1e6且1<=ai<=1e6,所以直接算乘积是不行的,a*b*c*d*...的素数因子和单独计算每一个的素数因子取交集是一样的。因为暴力是肯定不行的,所以我们需要计算每一个素数因子在每个区间里面的贡献。

        因为枚举每个数字复杂度为O(n),唯一分解定理数出素因子复杂度为O(logn),所以nlogn的复杂度是可以接受的。对于某个位置 i 处的数字,假设其某个素因子在位置 i 之前最近出现过的位置为 j ,则位置 i 处的数字的素因子对整个结果的贡献为:

(1)首先从 [i,n],该素因子被贡献(n - i + 1)次;

(2)在 j+1 处开始一直到 i,[j+1,n]、[j+2,n]、...[i,n]都是出现 i 处的该素因子,所以共贡献了:(i - j)*(n - i + 1) 次该素因子在 i 处时的贡献;

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1000000 + 7;
LL n,Num[maxn],prime[maxn],tot,PrimeIndex[maxn];
bool judge[maxn];
void init(){
   tot = 0;
   memset(judge,0,sizeof(judge));
   judge[1] = 1;
   for(int i = 2;i<maxn;i++){
       if(!judge[i])prime[tot++] = i;
       for(int j = 0;j<tot;j++){
           if(i*prime[j]>=maxn)break;
           judge[i*prime[j]] = 1;
           if(i%prime[j]==0)break;
       }
   }
}
int main()
{
   init();
   memset(PrimeIndex,0,sizeof(PrimeIndex));
   scanf("%d",&n);
   for(int i = 1;i<=n;i++)scanf("%lld",&Num[i]);
   LL sum = 0;
   for(int i = 1;i<=n;i++){
       LL m = Num[i];
       for(int j = 0;j<tot&&prime[j]*prime[j]<=m;j++){
            if(m%prime[j]==0){
                sum+=(n - i + 1)*(i - PrimeIndex[prime[j]]);
                PrimeIndex[prime[j]] = i;
                while(m%prime[j]==0)m/=prime[j];
            }
       }
       if(m > 1){
           sum+=(n - i + 1)*(i - PrimeIndex[m]);
           PrimeIndex[m] = i;
       }
   }
   printf("%lld\n",sum);
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿阿阿安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值