2017西安交大ACM小学期数论 [水题]
生活随笔
收集整理的這篇文章主要介紹了
2017西安交大ACM小学期数论 [水题]
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
水題
發布時間: 2017年6月25日 14:06?? 最后更新: 2017年7月3日 09:27?? 時間限制: 1000ms?? 內存限制: 128M
描述平均因數個數的統計對于估算數論題目復雜度具有非常重要的意義。小A同學聽了今天的課后,于是想要自己寫一個程序,求出1到n的平均因數個數。小A當然會啦!但是他想考考你。
輸入多組輸入數據(不超過1000組)。
每組一個正整數n(n≤109),如題目所述。
輸出1到n中的平均因數個數,精確到9位小數。
樣例輸入1 4 20170703 樣例輸出1 2.000000000 16.974173533 平均因數的個數計數,很簡單嘛1~n的因數的個數總數為
而由公式我們可以將上面的式子變換成為
也就是
對這個東西進行求和也是比較簡單的,注意不能暴力求和,因為時間復雜度太高了
我們考慮一個例子,當n為8的時候
[8/1]+[8/2]+[8/3]+[8/4]+[8/5]+[8/6]+[8/7]+[8/8]
=8+4+2+2+1+1+1+1
我們可以發現光1就出現了4次,2出現了2次,剩下的都出現了1次。這也就意味著,我們可以進行統計
我們統計除數為d的出現次數,那么d出現的次數可以表示為k = [n/d]-[n/(d+1)]
那么,它對答案的貢獻就是d*k,下一次d就變成了d+1
當我們第一次發現d出現1次的時候,這代表著下面所有的d也都只會出現一次了,我們求出這時候的分母f
將f循環到1,并直接暴力算出結果。
代碼:
#include <cstdio> #include <map> #include <iostream> using namespace std; typedef long long LL; int main(){LL n;while(scanf("%lld",&n) != -1){LL res = 0;LL d = 1;while(d <= n){//++cnt;LL nex = d+1;LL k = n/d - n/nex; if(k == 1){for(int i = n/d;i >= 1;i--){res += n / i;}break;}res += d*k;d = nex;}printf("%.9lf\n",double(res)/n);}return 0; }總結
以上是生活随笔為你收集整理的2017西安交大ACM小学期数论 [水题]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 思科和juniper都被嫌弃?那咱就把旧
- 下一篇: 2017西安交大ACM小学期数论 [完全