前 \(50\) 分基本是白給的。現在來討論 Subtask 5,也就是說求:
注意到如果令 \(g(i)\) 表示 \(\prod (-1)^{k_i}\),那么有 \(f_d(ij)=g(i)g(j)f_d(ij)^2\) 。此時令 \(h(i)\) 表示最大的 \(t\) 滿足 \(t^{d+1}|i\),那么可以發現 \(f_{d}(ij)^2=[h(ij)=1]=\sum\limits_{k|h(ij)}\mu (k)=\sum\limits_{t^{d+1}|ij}\mu (t)\) 。
此時考慮插入一個數怎么更新,具體考慮插入 \(r\),那么帶來的影響有:
此時考慮 \(t\) 的枚舉范圍,如果 \(t\not\mid r\) 的話,那么能夠滿足 \(t^{d+1}|lr\) 就一定存在質數 \(p\) 使得 \(p^{d+1}|l\),那么此時 \(f_d(lr)\) 必然為 \(0\),不需要考慮。
這樣插入一個數的時候就只需要考慮其因數作為 \(t\),然后求出 \(\frac{t^{d+1}}{\gcd (t^{d+1},r)}\) 后考慮 \(l\) 即可(每個 \(l\) 都放在其的每個因處)。那么我們就得到了 \(O(n\ln n)\) 的做法,關鍵思路就是重寫給定函數然后用莫比烏斯函數代替,最后找一下性質干掉無用情況。
順帶提一句,莫比烏斯函數有個性質是 \(\mu(ij)=\mu(i)\mu(j)\mu(ij)^2\) 。說白了上述的 \(f_d(ij)=g(i)g(j)f_d(ij)^2\) 其實就是將這個改寫了一下得到的。
接下來考慮上樹,注意到刪除加入一個點的代價都是其因數個數個,直接莫隊的話因為詢問區間左端點不重復,最后每個點操作的次數都是 \(O(\sqrt{n})\),那么總復雜度就是 \(O(n\ln n\sqrt{n})\) 。
接着考慮能不能做到更優,具體考慮鏈分治。每次繼承重子樹貢獻,重新計算輕子樹的貢獻,然后加入自身的貢獻。那么每一個點的加入次數是 \(O(\log n)\) 的,因此總復雜度為 \(O(n\ln n\log n)\) 。
我認為本題前 50 分和后 50 分之間的關鍵突破點在於怎么重寫 \(f_d(x)\) 使其變得更加好計算,得出上面的貢獻計算式后,接下來的無論是莫隊還是鏈分治都很自然並且很簡單了。
其實對於這類問題(最后轉化成了倍數或者因數做貢獻,總復雜度就變成了 \(O(n\ln n)\)),基本都會限制 \(a_i\) 是排列。這點給我們的啟發就是看到這種排列性質的話,如果又是這種數論題,那么可以想想是不是和倍數因數有關。