lg3708 koishi的數學題 [數學]
阿新 • • 發佈:2018-02-08
ace des 如果 fontsize line str 分享圖片 差分 net
Description
輸入一個整數n,設\(f(x)=\sum_{i=1}^n x~mod~i\),你需要輸出 $ f(1),f(2)...f(n)$
Input
一個正整數n。
Output
用空格分隔的n個整數$f(1),f(2)...f(n) $
思路
老師上課講的例題,方法真的很神奇。
觀察樣例,然後再繼續觀察。如果還是沒有發現什麽的話,就模擬打出一張表好了:(橫坐標為x, 縱坐標為y)
有沒有發現什麽神奇的地方。顯然每一橫行加起來就是答案,神奇的是在於縱行!(不要問我怎麽發現的)。
每一縱行的意義即是,對於一個固定的i, x遞增時的\(x ~mod ~ i\)。可以發現它是以i個為循環的數列。
處理上面一個數列復雜度較高,但是我們可以這樣處理:發現對於一個固定的i, x遞增時的\(x-(x ~mod ~ )i\),它便是每i項增加i的一個數列。於是我們可以每i個數打一個標記,標記意為增加i。
然後我們可以發現,f(x)可以從f(x-1)推到,便是$f(x-1)+n-1-標記。(類似於前綴和+差分維護吧)
代碼
#include <iostream> #include <algorithm> #include <cstdio> using namespace std; long long n,j,temp,ans,tag[MAXN]; //tag數組即為標記 int main(){ scanf("%lld",&n); for(int i=2; i<=n; i++) for(int j=i; j<=n; j+=i) tag[j]+=i; //處理tag數組,每i位加i for(int i=1; i<=n; i++) { ans+=n-tag[i]-1; printf("%lld ",ans); //遞推得出答案 } return 0; }
lg3708 koishi的數學題 [數學]