BZOJ2956: 模积和

Description

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

  

Input

第一行两个数n,m。

Output

  一个整数表示答案mod 19940417的值

Sample Input

3 4

Sample Output

1

样例说明
  答案为(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 mod 2) * (4 mod 3) + (3 mod 2) * (4 mod 4) + (3 mod 3) * (4 mod 1) + (3 mod 3) * (4 mod 2) + (3 mod 3) * (4 mod 4) = 1

数据规模和约定
  对于100%的数据n,m<=10^9。

Solution

题目就是求
\[ ∑_{i=1}^n∑_{j=1}^m[i≠j](n\space mod\space i)(m\space mod\space j) \]

先讨论不考虑i≠j的限制条件的情况
\[ \large \begin{align*} &\sum_{i=1}^n\sum_{j=1}^m(n\space mod\space i)(m\space mod\space j)\\ &=\sum\sum{(n-\frac{n}{i}*i)(m-\frac{m}{j}*j)}\\ &=\sum_{i=1}^{n}\sum_{j=1}^{m}{nm-\frac{n}{i}*i*m-n*\frac{m}{j}*j+i*j*\frac{n}{i}*\frac{m}{j}}\\ &=n^2m^2-nm^2\sum_{i=1}^{n}{\frac{n}{i}*i}-n^2*m\sum_{j=1}^m{\frac{m}{j}*j}+nm\sum_{i=1}^{n}{i*\frac{n}{i}*}\sum_{j=1}^{m}{j*\frac{m}{j}} \end{align*} \]
这是一种方法

然而还有更简便的方法
\[ \large \sum{n\space mod\space i}*\sum{m\space mod\space j} \]
直接用余数之和那题的方法求这个就好(不知道余数之和那题怎么写的戳这里

就不用上面一大堆码起来也麻烦的式子了

对于i==j的情况
\[ \large \begin{align*} &\sum_{i=1}^{k=min(n,m)}{(n-\frac{n}{i}*i)(m-\frac{m}{i}*i)}[i==j]\\ &=\sum_{i=1}^{k}{nm-m*\frac{n}{i}*i-n*\frac{m}{i}*i+i^2*\frac{n}{i}*\frac{m}{i}}\\ &=knm-km\sum_{i=1}^{k}{\frac{n}{i}*i}-kn\sum_{i=1}^{k}{\frac{m}{i}*i}+k\sum_{i=1}^{k}{i^2}\sum_{i=1}^{k}{\frac{n}{i}}\sum_{i=1}^{k}{\frac{m}{i}} \end{align*} \]
利用数论分块\(O(\sqrt{n})\)求出上面两式,将两式相减即可

P.S:\(\sum_{i=1}^n{i^2}=\frac{n*(n+1)*(2n+1)}{6}\)

#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define N 2010
#define mod 19940417
const ll m6 = 3323403;
ll n, m;
ll ans = 0;

ll sum(ll l, ll r) {
    return (r - l + 1) * (l + r) / 2 % mod;
}

ll calc(ll k) {
    ll ans = k * k % mod;
    for(int l = 1, r; l <= k; l = r + 1) {
        r = k / (k / l);
        ans = ((ans - sum(l, r) * (k / l) % mod) % mod + mod) % mod; 
    } 
    return ans;
}

ll cal(ll x) {
    return x * (x + 1) % mod * (2 * x + 1) % mod * m6 % mod;
}

ll sum2(ll l, ll r) {
    return (cal(r) - cal(l - 1) + mod) % mod;
} 

int main() {
    scanf("%lld%lld", &n, &m);
    if(n > m) swap(n, m);
    ans = calc(n) * calc(m) % mod;
    ans = ((ans - n * n % mod * m % mod) % mod + mod) % mod; 
    for(int l = 1, r; l <= n; l = r + 1) {
        r = min(n / (n / l), m / (m / l));
        ans = (ans + sum(l, r) * ((n/l)*m % mod + (m/l)*n % mod) % mod % mod);
        ans = (ans - sum2(l, r) * (n/l) % mod * (m/l) % mod + mod) % mod;
    }
    printf("%lld\n", (ans % mod + mod) % mod);
    return 0;
}
全部评论

相关推荐

06-13 17:33
门头沟学院 Java
顺序不记了,大致顺序是这样的,有的相同知识点写分开了1.基本数据类型2.基本数据类型和包装类型的区别3.==和equals区别4.ArrayList与LinkedList区别5.hashmap底层原理,put操作时会发生什么6.说出几种树型数据结构7.B树和B+树区别8.jvm加载类机制9.线程池核心参数10.创建线程池的几种方式11.callable与runnable区别12.线程池怎么回收线程13.redis三剑客14.布隆过滤器原理,不要背八股,说说真正使用时遇到了问题没有(我说没有,不知道该怎么回答了)15.堆的内存结构16.自己在写项目时有没有遇见过oom,如何处理,不要背八股,根据真实经验,我说不会17.redis死锁怎么办,watchdog机制如何发现是否锁过期18.如何避免redis红锁19.一个表性别与年龄如何加索引20.自己的项目的QPS怎么测的,有没有真正遇到大数量表21.说一说泛型22.springboot自动装配原理23.springmvc与springboot区别24.aop使用过嘛?动态代理与静态代理区别25.spring循环依赖怎么解决26.你说用过es,es如何分片,怎么存的数据,1000万条数据怎么写入库中27.你说用limit,那么在数据量大之后,如何优化28.rabbitmq如何批次发送,批量读取,答了延迟队列和线程池,都不对29.计网知不知道smtp协议,不知道写了对不对,完全听懵了30.springcloud知道嘛?只是了解反问1.做什么的?短信服务,信息量能到千万级2.对我的建议,基础不错,但是不要只背八股,多去实际开发中理解。面试官人不错,虽然没露脸,但是中间会引导我回答问题,不会的也只是说对我要求没那么高。面完问我在济宁生活有没有困难,最快什么时候到,让人事给我聊薪资了。下午人事打电话,问我27届的会不会跑路,还在想办法如何使我不跑路,不想扣我薪资等。之后我再联系吧,还挺想去的😭,我真不跑路哥😢附一张河科大幽默大专图,科大就是大专罢了
查看30道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务