七夕祭り(HDU - 1215)[シンプル] [数論]因子を見つけます
タグ:講義のトピックにストップを取得
タイトル説明
七夕の日には、デジタル領域に冗談を言って、彼は、ゲートに通知を掲載し、デジタル領域と、人々はあなたが通知に記載されているように、あなたの他の半分はそれを行うことが誰であるか知ってほしい」と述べた:? !それが「見つける
人々は予告になってきた前に、次のようにその予告の残りの半分が誰であるかを知りたい:
すべての正の整数少ないN Nよりもすることができ、すべての要素の数Nは、12 1の要因として、割り切れます、2,3,4,6-。
あなたは?それのあなたの他の半分を知りたい
入力
の入力データの最初の行は、デジタルT(1 <= T <=である 500000)、 テストケースの数を示します。その後、Tテストデータのセットは、各グループの試験データ番号N(1 <= N <= 500000)がある。
出力
テストデータの各セットのために、出力データ入力Nが他の半分の数を表す。
サンプル入力
3
2
10
20
サンプル出力
1
8
22
問題の意味
与えられた\(N- \) 、それを(自分自身を除く)のすべての要因を見つけ、合計はどのくらいですか?
解決
単純なアプローチは、再びサイクルにあるより\(N \)小さな数、及び各見\(I \)があるかどうか\(N \)因子(
n % i == 0
)、そしてもしそうであれば追加します。しかし、時間の複雑さがあるそうするために(O(N)\)\持っていたことができないデータのような大規模な量この質問のために、明らかに、。それを最適化します。我々は、多くの要因のために、びびりに完全な方形に加えことが判明\(\ SQRT {N} \ ) 因子以外、対になっています。実際には、限り、我々は\([2、\ SQRT { N}] \) 因子を見つけ、要素の範囲内でそれを見つけるために、他の要因も分割を行うことがわかりました。そのような時間の複雑さはれる\(O(\ N-SQRT {})\)は、この問題のために採用することができます。
コードで
/*
Problem
HDU - 1215
Status
Accepted
Time
312ms
Memory
1360kB
Length
667
Lang
G++
Submitted
2019-11-25 14:23:52
RemoteRunId
31628051
*/
#include <bits/stdc++.h>
using namespace std;
inline int read() //快读,读入速度比scanf()快.当输入数据量较大时,使用快读可以明显加快程序速度.
{
int res = 0;
char ch;
ch = getchar();
while(!isdigit(ch)){
ch = getchar();
}
while(isdigit(ch)){
res = (res << 3) + (res << 1) + ch - 48;
ch = getchar();
}
return res;
}
int main()
{
int times;
times = read();
while(times --){
int n, ans = 1;
n = read();
for(int i = 2; i * i <= n; i ++) //只要在[2,sqrt(n)]内找因数即可.
if(n % i == 0){
if(n / i != i)
ans += i + n / i;
else
ans += i; //注意出现完全平方数的sqrt(n)因子时,只加一次即可.
}
printf("%d\n", ans);
}
return 0;
}