1215 】七夕節(數論,約數和公式)
阿新 • • 發佈:2018-12-13
題幹:
七夕節那天,月老來到數字王國,他在城門上貼了一張告示,並且和數字王國的人們說:"你們想知道你們的另一半是誰嗎?那就按照告示上的方法去找吧!" 人們紛紛來到告示前,都想知道誰才是自己的另一半.告示如下:
數字N的因子就是所有比N小又能被N整除的所有正整數,如12的因子有1,2,3,4,6. 你想知道你的另一半嗎?
Input
輸入資料的第一行是一個數字T(1<=T<=500000),它表明測試資料的組數.然後是T組測試資料,每組測試資料只有一個數字N(1<=N<=500000).
Output
對於每組測試資料,請輸出一個代表輸入資料N的另一半的編號.
Sample Input
3 2 10 20
Sample Output
1 8 22
解題報告:
約數和,可以打表,可以直接算。
AC程式碼1:(打表)(93ms,打表的i那層迴圈到500000/2,則78ms)
#include<bits/stdc++.h> using namespace std; int num[500000 + 5],n; int main() { for(int i = 1; i<=500000; i++) { for(int j = 2*i; j<=500000; j+=i) { num[j] += i; } } int t; cin>>t; while(t--) { scanf("%d",&n); printf("%d\n",num[n]); } return 0 ; }
AC程式碼2:(不打表,Tsqrtn的複雜度)(296ms)
#include <bits/stdc++.h> #define ll long long using namespace std; const int MAX = 1e5+10; int p[MAX]; int a[MAX]; ll qpow(ll a,ll b) { ll ans = 1; while(b){ if(b & 1) ans *= a; b >>= 1; a *= a; } return ans; } int main() { int t; scanf("%d",&t); while(t--){ int n; scanf("%d",&n); int cnt = 0; int tmp = n; // memset(a,0,sizeof a); for(int i = 2; i * i <= n; i++) { if(tmp % i == 0) { p[++cnt] = i; a[cnt]=0 ; while(tmp % i == 0) { a[cnt]++; tmp /= i; } } } if(tmp != 1) { p[++cnt] = tmp; a[cnt] = 1; } ll ans = 1; for(int i = 1; i<=cnt; i++) { ans *= (qpow(p[i],a[i]+1) - 1) / (p[i]-1); } printf("%lld\n",ans-n);//因為最後要輸出的是除去自己的,因為是因子,因子不包括自己。 } return 0; }
總結: 這題你如果對a陣列進行直接memset,那恭喜你,超時了。 因為T太大了,不能直接memset,只能初始化到sqrt才可以。這是比較坑的一個地方。