J. Prime Game(超详解)(2018icpc南京站区域赛)
题目
大体意思就是多个数累乘,然后把里边的质因数的个数相加,并且在一次累乘中相同的质因数不能重复加。(为什么这道题在大佬们的博客里的定位是水题)
知识点
质因数:这道题中出现了质因数这个概念,即为既是质数又同时必须是某个数的因数。
质因数分解:每个合数都可以写成几个质数相乘的形式,其中每个质数都是这个合数的因数,把一个合数用质因数相乘的形式表示出来,叫做分解质因数。
如30=2×3×5 。分解质因数只针对合数。
实现代码:
#include <iostream> using namespace std; int main() { int n, n2; cin >> n; cout << n << "="; n2 = n; if(n < 2)return 0; for (int i = 2; i*i <= n2; i++) { while (n2%i == 0) { n2 = n2 / i; cout << i; if (n2 != 1)cout << "*"; } } if( n2 != 1) cout << n2; return 0; }
具体思路
就拿样例2来推一共10个数,6,7,5,5,4,9,9,1,8,12
第一个数6的质因数为2,3 那么这两个数应该在
fac(1,1),fac(1,2),......fac(1,10)中都累加一次,即有2×10=20
第二个数7的质因数只有7,那么它应该在
fac(1,2),fac(1,3),.......fac(1,10) 共9个
fac(2,1),fac(2,2),.......fac(2,10) 共10个
又因为fac(2,1)和fac(1,2)重复,所以一共10+9-1=18
第三个数5的质因数只有5,故
fac(1,3),fac(1,4),.......fac(1,10) 共8个
fac(2,3),fac(2,4),.......fac(2,10) 共8个
fac(3,1),fac(3,2),.......fac(3,10) 共10个
又因为fac(1,3)fac(2,3)分别和fac(3,1),fac(3,2)重复,所以8+8+10-2=24
第四个数也为5,那么在
fac(1,4),fac(1,5),.......fac(1,10) 共7个
fac(2,4),fac(2,5),.......fac(2,10) 共7个
fac(3,4),fac(3,5),.......fac(3,10) 共7个
fac(4,1),fac(4,2),.......fac(4,10) 共10个
又因为有3个重复的,所以7+7+7+10-3=28吗?
在上一个5中已经有24个加了5这个质因数了,所以应该为7+7+7+10-24=7
……
综上,我们可以推断出一个公式
在第i个数时,对于其每个质因数共有
(n-i+1)*(i-上一次此质因数出现的位置,初始为0)
有了这个公式就很简单了,枚举每个a[i]相加公式即可
AC代码
#include<iostream> using namespace std; long long sum=0; int n; long long pre[1000010]; void solve(long long x,int pos) { for(int i=2;i*i<=x;i++) { if(x%i!=0) continue; while(x%i==0) x/=i; sum+=(n+1-pos)*(pos-pre[i]); pre[i]=pos; } if(x!=1) { sum+=(n+1-pos)*(pos-pre[x]); pre[x]=pos; } } int main() { long long a[1000010]; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); for(int i=1;i<=n;i++) { solve(a[i],i); } printf("%lld",sum); return 0; }