portal
考慮這樣乙個式子:
\[d(ij) = \sum_\sum_ [x \bot y]
\]怎麼證明? 一開始我們一定會想到$$d(ij) = \sum_ \sum_ 1 $$ 但這樣會計算重複. 於是我們考慮:
\[d(ij) = \sum_\sum_ | j}1
\]這樣每個因數就變成$ \frac $, 如果x和y不互質. 那麼就會有 $ \frac == \frac $
如果xp
,yp
同時是i, j的因數那就會算重複.
所以一定要求此二者互質.
相應的:
\[\sigma(ij) = \sum_\sum_ [x \bot y]x \frac{}{} \frac
\]那麼我們可以開始化式子了!!
\[ans = \sum_\sum_ \sum_\sum_[(x, y) == 1] \\
= \sum_ \sum_[(x, y) == 1]\sum_ \sum_ [x | i][y | j] \\
= \sum_ \sum_\sum_ \mu(d) \lfloor\frac \rfloor\lfloor\frac \rfloor\\
= \sum_ \mu(d) \sum_\sum_[d | x][d | y] \lfloor\frac \rfloor\lfloor\frac \rfloor \\
= \sum_ \mu(d) \sum_^\lfloor\frac \rfloor\sum_^\lfloor\frac \rfloor\\
\]令\(f(n) = \sum_^ \sigma_0(i)\)
那麼有\[ans = \sum_ \mu(d) f(\frac)f(\frac)
\]然後線性篩/杜教篩min25篩
洲閣篩篩以下約數個數的字首和就可以做了.
#includeusing namespace std;
#define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i)
#define clar(a, b) memset((a), (b), sizeof(a))
#define debug(...) fprintf(stderr, __va_args__)
typedef long long ll;
typedef long double ld;
int read()
void write(int x)
const int maxn = 50009;
int prime[maxn], isnprime[maxn], mu[maxn], prefixmu[maxn], tot, low[maxn];
ll sigma0[maxn];
void linearsieve() else
} }rep (i, 1, maxn - 1)
}void init()
void solve()
printf("%lld\n", ans); }}
int main()
SDOI2015 約數個數和
description input 輸入檔案包含多組測試資料。第一行,乙個整數t,表示測試資料的組數。接下來的t行,每行兩個整數n m。output t行,每行乙個整數,表示你所求的答案。sample input 2 7 45 6 sample output 110 121data constrai...
SDOI2015 約數個數和
慢慢化柿子吧 要求的是這個 sum n sum md ij 神奇的約數個數函式有乙個這樣的性質 d ij sum sum x,y 1 試著從唯一分解定理的角度去理解,將 i,j 分別分解質因數 顯然 d ij 應該等於每乙個 p 在 i,j 中分解出來的指數加起來加1再相乘 所以分別列舉所有約數的話...
題解 SDOI2015 約數個數和
link 又到了喜聞樂見的推式子環節 引理 d i,j sum sum gcd u,v 1 證明 等會補。sum n sum m sum sum gcd u,v 1 sum n sum m lfloor frac n u rfloor lfloor frac m v rfloor gcd u,v 1...