Time Limit: 10 Sec  Memory Limit: 128 MB

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

这里是链接:【BZOJ】2956:模积和

这里是题解:

首先,暴力枚举将会很凄惨:O(nm)。早就 GG ( Time Limit Exceeded )了。

所以从公式入手:原公式是:

展开为:

观察式子:[n mod i](同理 m mod j)

根据mod的定义可以将上式写成这个样子:

[n/i]向下取整,就是C++中的整型(n/i),然后再乘以 i 就相当于下图灰色区域,

再用n减掉就能得到mod后的值。【下图模拟mod的转化

所以式子就可以简化为:

注意:因为题目中i!=j,所以当i、j 相同就直接减掉】

然而这样还是O(n^2)的复杂度。

所以继续化简:将第一个式子的Σ移动,使时间复杂度变为O(n)

这里是最终式子:

能够移动Σ的证明:设n-[n/i]*i为Xi,m-[m/j]*j为Yj。

(下图有点错误:n、m的值应该是不同的,但是n、m不同的证明也是这样的。)

这个是原式子展开的ans:

  这个是化简后展开的ans:

显然它们的ans值是相等的。那么,第一步化简式子已经完成了。

虽然移动Σ已经将复杂度降低到O(n),但很不幸的是依然过不了

考虑如何优化

低于O(n)的复杂度一般就三种:O(1)、O(logn)、O(√n)

注意最终式子,都有一个式子like this:[n/i](其中n为一个定值,i是从1到n的一个变量。)

但是这里有个很美妙的事情就是:

假如n==1000时,i在91~100之间,n/i的值都是为10的;

假如n==100000000时,i在9090910~10000000之间,n/i的值都是为10的。

这里因为在某一个区间中的值都是相等的。所以我们可以很愉快地利用分块的思想

那么怎么算这个块的大小呢?

假设有一个块里面的[n/i]的值都是为k,那么其区间就是:[(n/(k+1))+1,n/k].

推导:因为[n/i]是向下取整的,所以k*i<=n,n/k为定值,所以i<=n/k,但i一定也有下界,所以i>n/(k+1),

即i>=n/(k+1)+1.

注意:分块求值套用公式的时候需要除法,并不能先取模,然而不先取模会爆long long.

但好在除的数是固定的6,所以就直接在求平方和的时候,MOD开大6倍,最后再模回去就行了。

(其实反过来也就是网上普遍流传的3323403,是[mod/6]的值)

这里是代码:

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. #include<algorithm>
  5. #define LL long long
  6. #define mod 19940417
  7. #define MOD 119642502
  8. using namespace std;
  9. LL n,m,tmp1,tmp2,ans,ine;
  10.  
  11. LL sum(LL x){
  12. return x*(x+)/%mod;
  13. }
  14.  
  15. LL SUM(LL x){
  16. return x*(x+)%MOD*(*x+)%MOD/;
  17. }
  18.  
  19. LL calc(LL x){
  20. LL ans=x*x%mod;
  21. for(LL i=;i<=x;i=tmp1+){
  22. tmp1=x/(x/i);//(x/i)求k的值,n/k为块的上界
  23. ans=(ans-(x/i)*(sum(tmp1)-sum(i-)+mod)%mod)%mod;
  24. }
  25. return ans%mod;
  26. }
  27.  
  28. int main(){
  29. scanf("%lld %lld",&n,&m);
  30. if(n>m) swap(n,m);
  31. ans=calc(n)*calc(m)%mod;
  32. //处理i,j相同情况
  33. for(LL i=;i<=n;i=tmp2+){
  34. tmp2=min(n/(n/i),m/(m/i));
  35. ans=(ans-n*m%mod*(tmp2-i+)%mod
  36. +m*(n/i)%mod*(sum(tmp2)-sum(i-)+mod)%mod
  37. +n*(m/i)%mod*(sum(tmp2)-sum(i-)+mod)%mod
  38. -(n/i)*(m/i)%mod*(SUM(tmp2)-SUM(i-)+mod)%mod+*mod)%mod;
  39. }
  40. printf("%lld",ans%mod);
  41. return ;
  42. }

【BZOJ】2956

梦想总是要有的,万一实现了呢?

【BZOJ】2956:模积和的更多相关文章

  1. BZOJ 2956 模积和 (数学推导+数论分块)

    手动博客搬家: 本文发表于20170223 16:47:26, 原地址https://blog.csdn.net/suncongbo/article/details/79354835 题目链接: ht ...

  2. BZOJ 2956 模积和

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2956 题意:给出n和m.计算: 思路: i64 n,m; i64 cal(i64 m,i ...

  3. [Bzoj 2956] 模积和 (整除分块)

    整除分块 一般形式:\(\sum_{i = 1}^n \lfloor \frac{n}{i} \rfloor * f(i)\). 需要一种高效求得函数 \(f(i)\) 的前缀和的方法,比如等差等比数 ...

  4. BZOJ 2956 模积和(分块)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2956 [题目大意] 求∑∑((n%i)*(m%j))其中1<=i<=n,1 ...

  5. bzoj 2956: 模积和 ——数论

    Description 求∑∑((n mod i)*(m mod j))其中1<=i<=n,1<=j<=m,i≠j. Input 第一行两个数n,m. Output 一个整数表 ...

  6. 【BZOJ】2956: 模积和

    题意 求\(\sum_{i=1}^{n} \sum_{j=1}^{m} (n \ mod \ i)(m \ mod \ j)[i \neq j] \ mod \ 19940417\), \((n, m ...

  7. 「BZOJ 2956」模积和

    「BZOJ 2956」模积和 令 \(l=\min(n,m)\).这个 \(i\neq j\) 非常不优雅,所以我们考虑分开计算,即: \[\begin{aligned} &\sum_{i=1 ...

  8. BZOJ_2956_模积和_数学

    BZOJ_2956_模积和_数学 Description 求∑∑((n mod i)*(m mod j))其中1<=i<=n,1<=j<=m,i≠j. Input 第一行两个数 ...

  9. P2260 [清华集训2012]模积和

    P2260 [清华集训2012]模积和 整除分块+逆元 详细题解移步P2260题解板块 式子可以拆开分别求解,具体见题解 这里主要讲的是整除分块(数论分块)和mod不为素数时如何求逆元 整除分块:求Σ ...

随机推荐

  1. 【Windows定时关机】windows实现定时关机与取消

    背景:本人昨晚本来打算将电脑设置为晚上12点 30定时关机,结果写成了:12:30,所以就在刚才,我正玩游戏的时候, 电脑弹出提示:“windows将在一分钟内关闭”,我刚开始一脸懵逼,后来打开昨天敲 ...

  2. 六、Django之Template

    一.Template由来 1.任何前端页面的改动都和后端有关: 2.前端HTML和后端python分开能让网站更加清晰: 3.前后端分离的趋势下,专业的事交给专业的人做. 二.Django中的temp ...

  3. XAF-如何在详细视图界面显示按钮(含示例项目下载)

    默认情况下,指定了按钮的Category后,将在对应的按钮容器显示按钮.有时候,我们需要将按钮显示在详细视图中. 本示例源码 创建一个控制器,并填加按钮.设置好了所有ID.Caption后,给Cate ...

  4. 【坚持】Selenium+Python学习之从读懂代码开始 DAY2

    2018/05/10 [来源:菜鸟教程](http://www.runoob.com/python3/python3-examples.html) #No.1 # 二次方程式 ax**2 + bx + ...

  5. arcgis--arcmap导出点的X,Y坐标

    arcmap操作的

  6. 选题博客:北航iCourse课程信息平台

    1. 用户调查 在选题的时候,我们面向北航所有本科在读本科生,发布了<北航信息平台用户调查>.此次问卷调查共回收有效问卷95份. 1.1 功能需求调查 调查其中一项是让同学们对平台功能进行 ...

  7. TCP半开连接与半闭连接

    半打开(Half-Open)连接和半关闭(Half-Close)连接.TCP是一个全双工(Full-Duplex)协议,因此这里的半连接"半"字就是相对于全双工的"全&q ...

  8. 5 种使用 Python 代码轻松实现数据可视化的方法

    数据可视化是数据科学家工作中的重要组成部分.在项目的早期阶段,你通常会进行探索性数据分析(Exploratory Data Analysis,EDA)以获取对数据的一些理解.创建可视化方法确实有助于使 ...

  9. Python20-Day02

    1.数据 数据为什么要分不同的类型 数据是用来表示状态的,不同的状态就应该用不同类型的数据表示: 数据类型 数字(整形,长整形,浮点型,复数),字符串,列表,元组,字典,集合 2.字符串 1.按索引取 ...

  10. 20135208JAVA第二次试验

    北京电子科技学院(BESTI) 实     验    报     告 课程:Java程序设计  班级:1352 姓名:贺邦  学号:20135208 成绩:             指导教师:娄嘉鹏  ...