題目大意:x能整除n,x就是n的positive proper divisor,但n本身不算,給你兩個數n和d,找出所有小於n的數中,最大positive proper divisor是d個數,t組測試資料。
解題思路:很明顯對於每個數x,找出其最小素因數m,如果x/m等於d,那麼x的最大positive proper divisor就是d,如果這樣列舉小於n的每乙個數,總共需要 t n √n的時間。
還有更優的做法,我們可以直接素數篩篩出所有的素數,另每個素數x乘d,一定滿足x<=d&&x*d分兩種情況,第一種情況是d是素數,我們只要列舉素數x就好,如果x小於等於d且x×d小於n就讓ans++,否則終止迴圈。
第二種情況是d不是素數,我們假設d=5×7×11,很明顯當
x=2,x*d=2 ×5×7×11 或者x=3,x*d=3×5×7×11 或 x*d= 5 ×5×7×11都可以 ,x*d的最大positive proper divisor都是d
,如果x=7,x*d= 7×5×7×11的話,最大positive proper divisor是7×7×11,不為d就不滿足條件,所以我們可知,我們列舉的素數小於等於d的最小素數就好了。操作跟一種情況一樣,加上一句如果d%x==0且x!=d,break,就好了,這種說明d不是素數,小於d的素數已經被計算過。
另附兩種素數打表**,乙個快乙個慢
快速素數打表:
//prime儲存了小於n的素數,下標從1開始
//visit陣列標記了是否為素數,bool型別
//返回值num表示小於n的素數的個數
ll prime[maxn];
bool visit[maxn];
ll init_prim(ll n)
for (ll j = 1; ((j <= num) && (i * prime[j] <= n)); ++j)
}return num;//返回質數個數
}
比較慢的一種素數打表
int maxn=100000;
int vis[maxn];
ll init_prim(ll n)}}
}
題目ac**:
#include #include #include #include #include #include #include #include #include using namespace std;
#define inf 0x3f3f3f3f
#define ull unsigned long long
#define maxn 100010
typedef long long ll;
typedef long long ll;
//prime儲存了小於n的素數,下標從1開始
//visit陣列標記了是否為素數,bool型別
//返回值num表示小於n的素數的個數
ll prime[maxn];
bool visit[maxn];
ll init_prim(ll n)
for (ll j = 1; ((j <= num) && (i * prime[j] <= n)); ++j)
}return num;//返回質數個數
}int main()
printf("%i64d\n",ans);
}return 0;
}
素數篩法打表
篩法打素數表是一種高效的打表方法,具體做法是 先把n個自然數按次序排列起來。1不是質數,也不是合數,要划去。第二個數2是質數留下來,而把2後面所有能被2整除的數都劃去。2後面第乙個沒劃去的數是3,把3留下,再把3後面所有能被3整除的數都劃去。3後面第乙個沒劃去的數是5,把5留下,再把5後面所有能被5...
素數打表 篩法
打表 是一種典型的用空間換時間的做法,一般指將所有可能需要用到的結果事先計算出來,這樣以後後面需要用到時就可以直接查表獲得。在什麼情況下我們需要打表?1 在程式中一次性計算出所有需要用到的結果,之後查詢直接取這些結果。舉個例子,假如我們算fibonacci數中的f n 我們假如需要算很多次q次 比如...
篩法素數打表方法
埃拉託斯特尼篩法,是一種西元前250年由古希臘數學家埃拉託斯特尼所提出的一種簡單檢定素數的演算法。給出要篩數值的範圍n,找出以內的素數。先用2去篩,即把2留下,把2的倍數剔除掉 再用下乙個質數,也就是3篩,把3留下,把3的倍數剔除掉 接下去用下乙個質數5篩,把5留下,把5的倍數剔除掉 不斷重複下去....