zoukankan      html  css  js  c++  java
  • [清华集训2012]模积和

    Description

    Luogu2260
    BZOJ2956

    [sum_{i=1}^{n}sum_{j=1}^{m} (nmod i)(mmod j)[i e j] ]

    Solution

    看到取模就会想整除分块的吧,那个([i e j])其实也很好处理啊,就是最后再减去(i=j)的情况就行了。
    我式子推的有点丑……

    [sum_{i=1}^{n}sum_{j=1}^{m} (nmod i)(mmod j)[i e j]\ = sum_{i=1}^{n}sum_{j=1}^{m} (nmod i)(mmod j) - sum_{i=1}^{min(n, m)} (nmod i)(mmod i)\ = sum_{i=1}^{n}sum_{j=1}^{m} (n - lfloordfrac{n}{i} floor i)(m - lfloordfrac{m}{j} floor j) - sum_{i=1}^{min(n, m)} (n - lfloordfrac{n}{i} floor i)(m - lfloordfrac{m}{i} floor i)\ = sum_{i=1}^{n}sum_{j=1}^{m} (nm - mlfloordfrac{n}{i} floor i - nlfloordfrac{m}{j} floor j + lfloordfrac{n}{i} floor ilfloordfrac{m}{j} floor j) - sum_{i=1}^{min(n, m)}mbox{...}\ = n^2m^2 - m^2sum_{i=1}^{n}lfloordfrac{n}{i} floor i - mbox{...} ]

    后面就是一些sb的去括号了,没啥好说的了。

    Code

    #include <cstdio>
    #include <algorithm>
    
    typedef long long LL;
    const LL MOD = 19940417;
    const LL I2 = 9970209;
    const LL I6 = 3323403;
    
    int n, m;
    
    LL sp(LL x) {
        return x * (2 * x + 1) % MOD * (x + 1) % MOD * I6 % MOD;
    }
    
    int main() {
    	scanf("%d%d", &n, &m);
    	if (n < m) std::swap(n, m);
    	LL ans = n % MOD * n % MOD * m % MOD * m % MOD;
    	LL si = 0, sj = 0, sij = 0;
    	for (int i = 1, j; i <= n; i = j+1) {
    		j = n / (n / i);
    		si = (si + (n / i) * (i + j) % MOD * (j - i + 1) % MOD * I2 % MOD) % MOD; 
    	}
    	for (int i = 1, j; i <= m; i = j+1) {
    		j = m / (m / i);
    		sj = (sj + (m / i) * (i + j) % MOD * (j - i + 1) % MOD * I2 % MOD) % MOD; 
    	}
    	ans = ((ans - m % MOD * m % MOD * si % MOD - n % MOD * n % MOD * sj % MOD) %MOD + MOD) % MOD;
    	sij = si * sj % MOD;
    	ans = (ans + sij) % MOD;
    	ans = (ans - m % MOD * m % MOD * n % MOD + MOD) % MOD;
    	si = 0;
    	for (int i = 1, j; i <= m; i = j+1) {
    		j = std::min(m, n / (n / i));
    		si = (si + (n / i) * (i + j) % MOD * (j - i + 1) % MOD * I2 % MOD) % MOD; 
    	}
    	ans = (ans + m % MOD * si % MOD + n % MOD * sj % MOD) % MOD;
    	sj = 0;
    	for (int i = 1, j; i <= m; i = j+1) {
    		j = std::min(n / (n / i) , m / (m / i));
    		sj = (sj + (n / i) % MOD * (m / i) % MOD * (sp(j) - sp(i-1) + MOD) % MOD) % MOD; 
    	}
    	ans = (ans - sj + MOD) % MOD;
    	printf("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    Android 5.X新特性之RecyclerView基本解析及无限复用
    Android 网络框架之Retrofit2使用详解及从源码中解析原理
    Android 源码解析之AsyncTask
    Business Logic
    WHO AM I
    黑洞
    俄罗斯方块
    还记得八皇后的解法吗
    汝之蜜糖,吾之砒霜
    项目为什么会失败
  • 原文地址:https://www.cnblogs.com/wyxwyx/p/lg2260.html
Copyright © 2011-2022 走看看