bzoj2956 模積和 數論

2022-05-20 18:12:03 字數 1004 閱讀 8936

題目描述

求∑∑((n mod i)*(m mod j))其中1<=i<=n,1<=j<=m,i≠j。

輸入第一行兩個數n,m。

輸出乙個整數表示答案mod 19940417的值

樣例輸入

3 4樣例輸出1題解

數論+分塊

由於直接求i≠j的情況比較難搞,所以我們可以先求出i可以等於j的和,然後再減去i等於j時的情況。

也就是求∑∑((n mod i)*(m mod j))-∑((n mod i)*(m mod i))。

然後再根據乘法分配律轉化為∑(n mod i)*∑(m mod i)-∑((n mod i)*(m mod i))。

因為有n mod i = n-(n/i)*i(這裡的除號均表示向下取整)。

所以∑(n mod i) = ∑(n-(n/i)*i) = n*n-∑((n/i)*i)。

這裡n/i最多只有√n 種取值,我們可以分塊來求,這裡用到1,2,3,...,n的和。

後面一坨變為∑((n-(n/i)*i)*(m-(m/i)*i))=∑(nm-m*(n/i)*i-n/(m/i)*i+(n/i)*(m/i)*i^2)。

同樣的方法處理,運用一下1^2,2^2,3^2,...,n^2的和。

最後減一下即可。

然而有乙個問題,就是套用公式的時候需要除法,不能先取模,而不先取模還會爆long long。

好在除的數是固定的2和6,於是可以直接把mod開大6倍,最後再模回去即可。

#include #include #define mod 119642502

using namespace std;

typedef long long ll;

ll sum1(ll p)

ll sum2(ll p)

ll calc1(ll n)

return ans;

}ll calc2(ll n , ll m)

return ans;

}int main()

bzoj 2956 模積和 數論

求 n mod i m mod j 其中1 i n,1 j m,i j。第一行兩個數n,m。乙個整數表示答案mod 19940417的值 3 41 樣例說明 答案為 3 mod 1 4 mod 2 3 mod 1 4 mod 3 3 mod 1 4 mod 4 3 mod 2 4 mod 1 3 m...

bzoj2956 模積和(數論)

先算出無限制的情況,再減去i j的情況。無限制的情況很好算,有限制的情況需要將式子拆開。注意最後的地方要用平方和公式,模數 1是6的倍數,於是逆元就是 模數 1 6 include include include include define mod x x mod?x mod x using na...

bzoj2956 模積和 (分塊)

原題位址 題意 求 n mod i m mod j 其中1 i n,1 j m,i j。答案 mod 19940417 資料範圍 n,m 10 9 題解 n i 1 mj 1 nm odi mm odj i j ni 1 mj 1 nmod i mmod j min n,m i 1 nm odi m...