UVa 516

UVa 516

題目

http://domen111.github.io/UVa-Easy-Viewer/?516

給一個數字 $X$ 質因數分解後式,求 $X-1$ 的質因數分解式

想法

可以利用 stringstream 讀取輸入,取得所有數值就可以拿到 $X$ 以及 $X’=X-1$

至於質因數分解的部分,我們可以藉由質數篩的過程當中紀錄每個數字第一次是被誰篩掉(也就是最小因數)

例如: 10 -> 2 9 -> 3 17 -> 17

如此一來,對於每個詢問 $X’$ 每次先找到最小因數 $p$ ,紀錄當前的值 $X’$ 可以被整除幾次,並且將 $X’$ 除以 $p$,直到 $X’$ 為 $1$ 的時候表示我們已經找完了

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//By Koios1143
#include<iostream>
#include<sstream>
#include<cmath>
const int MaxN = 32768;
int fact[MaxN], ans[MaxN][2];
using namespace std;
string s;
bool fir;
int x,n,a,b,p,cnt,px;
int main(){
// 質數篩
for(long long i=2 ; i<=MaxN ; i++){
if(!fact[i]){
fact[i]=i;
for(long long j=i*i ; j<=MaxN ; j+=i){
if(!fact[j]){
fact[j]=i;
}
}
}
}

while(getline(cin,s)){
if(s=="0") break;
fir=true; n=1; px=0;

// 計算 X
stringstream ss;
ss<<s;
while(ss>>x){
if(fir) a=x;
else{
b=x;
n*=pow(a,b);
}
fir=!fir;
}
n--;

// 質因數分解
while(n!=1){
p=fact[n];
cnt=0;
while(n%p==0){
cnt++;
n/=p;
}
ans[px][0]=p;
ans[px][1]=cnt;
px++;
}

for(int i=px-1 ; i>=0 ; i--){
if(i!=px-1) cout<<" ";
cout<<ans[i][0]<<" "<<ans[i][1];
}
cout<<"\n";
}
return 0;
}

複雜度分析

質數篩的複雜度為 $O(NloglogN)$

每筆測資計算 $X$ 時間複雜度約為 $O(\Omega(X))$

每筆測資質因數分解時間複雜度約為 $O(\Omega(X))$

每筆測資輸出時間複雜度約為 $O(\Omega(X))$

其中, $\Omega(X)$ 表示 $X$ 的不同質因數個數。$\Omega(X)$ 表示 $X$ 的質因數個數

總時間複雜度約為 $O(NloglogN + 2\Omega(X) + \Omega(X))$