南京区域赛--Prime Game--计算贡献+欧拉筛

Input

The first line contains one integer nn (1 \le n \le 10^61≤n≤106) \text{---}— the length of the sequence.

The second line contains nn integers a_iai​ (1 \le i \le n, 1 \le a_i \le 10^61≤i≤n,1≤ai​≤106) \text{---}— the sequence.

Output

Print the answer to the equation.

样例输入1复制

10
99 62 10 47 53 9 83 33 15 24

样例输出1复制

248

样例输入2复制

10
6 7 5 5 4 9 9 1 8 12

样例输出2复制

134

题目来源

ACM-ICPC Nanjing Onsite 2018

先利用欧拉筛法预处理出所有数的最小质因子。对于每一个数v来说,统计它的质因子可以作用到的范围,枚举它左右可以的区间。 

#include <algorithm>    //STL通用算法
#include <bitset>     //STL位集容器
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex>     //复数类
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>      //STL双端队列容器
#include <exception>    //异常处理类
#include <fstream>
#include <functional>   //STL定义运算函数(代替运算符)
#include <limits>
#include <list>      //STL线性列表容器
#include <map>       //STL 映射容器
#include <iomanip>
#include <ios>      //基本输入/输出支持
#include<iosfwd>     //输入/输出系统使用的前置声明
#include <iostream>
#include <istream>     //基本输入流
#include <ostream>     //基本输出流
#include <queue>      //STL队列容器
#include <set>       //STL 集合容器
#include <sstream>    //基于字符串的流
#include <stack>      //STL堆栈容器    
#include <stdexcept>    //标准异常类
#include <streambuf>   //底层输入/输出支持
#include <string>     //字符串类
#include <utility>     //STL通用模板类
#include <vector>     //STL动态数组容器
#include <cwchar>
#include <cwctype>
#define ll long long
using namespace std;
//priority_queue<int,vector<int>,less<int> >q;
int dx[]= {-1,1,0,0,-1,-1,1,1};
int dy[]= {0,0,-1,1,-1,1,1,-1};
const int maxn = 1000000+66;
const ll mod=1e9+7;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
int phi[maxn+10],prime[maxn+10],tot,ans;
bool vis[maxn+10];//标记素数
int minP[maxn];
inline void sieve(int x)
{
    phi[1] = 1;
    int len=0;
    for(int i=1;i<=x;i++)minP[i]=i;
    for(int i = 2; i <= x; i ++)
    {
        if(! vis[i])
        {
            prime[++ len] = i;
            phi[i] = i - 1;	//因为欧拉函数代表小于这个数的且与这个数互质的数的个数,所以质数的欧拉函数为它本身减1
        }
        for(int j = 1; j <= len && i * prime[j] <= x; j ++)
        {
            vis[i * prime[j]] = 1;
            minP[i * prime[j]] = prime[j];
            if(i % prime[j] == 0)
            {
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            }
            phi[i * prime[j]] = phi[i] * (prime[j] - 1);
        }
    }
}
int a[maxn];
int low[maxn];
int main()
{
    sieve(maxn);
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        int v=a[i];
        while(v!=1)
        {
            int x=minP[v];
            ans+=(ll)(n-i+1)*(i-low[x]);
            low[x]=i;
            while(minP[v]==x)
            {
                v/=x;
            }
            //cout<<"++"<<endl;
        }
        //cout<<"---"<<endl;
    }
    cout<<ans<<endl;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值