題目描述
求∑∑((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 119642502using 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...