首页 > 其他分享 >【数论】数论分块

【数论】数论分块

时间:2024-08-19 13:05:31浏览次数:15  
标签:lfloor frac 分块 数论 rfloor Large int mathcal

2024-18-19 ·最后更新时间:2024-18-19

\(\Large\mathcal{1,solution(1)}\)
如果我们把数 \(n\) 与小于等于 \(n\) 的数 \(i\) 的对应关系打印在表格上会是这样。

\(i\) 1 2 3 4 5 6 7 8 9 10
\(\Large\lfloor\frac{n}{i}\rfloor\) 10 5 3 2 2 1 1 1 1 1

可以发现 \(\Large\lfloor\frac{n}{i}\rfloor\) 的数是有重复的,那么我们可不可以根据重复的特点来计算 \(\Large\lfloor\frac{n}{i}\rfloor\) 的数值呢?答案是可以的,这也就是数论分块的主要思想。

\(\Large\mathcal{2,verification}\)
为了保证算法的正确性我们要对其进行时间复杂度分析。

  1. 当 \(i>\sqrt{n}\) 时,那么此时 \(\Large\lfloor\frac{n}{i}\rfloor\) 最多有 \(\sqrt{n}\) 种取值。
  2. 当 \(i\leq\sqrt{n}\) 时,那么此时 \(\Large\lfloor\frac{n}{i}\rfloor\) 也最多有 \(\sqrt{n}\) 种取值。

所以最终我们可以得到时间复杂度为 \(O(\sqrt{n})\)

\(\Large\mathcal{3,solution(2)}\)
接下来我们将要对边界进行分析,判断什么时候当前在哪一个块中。

首先我们假设当前块的左端点是 \(l\) ,那么根据我们之前的分析 \(\lfloor\frac{n}{l}\rfloor\) 就一定是我们当前块的数值,那么右端点该怎么求,对右端点 \(r\) 进行分析,其本质上就是满足 \(\lfloor\frac{n}{l}\rfloor=\lfloor\frac{n}{r}\rfloor\) 的 \(r\) 的最大值,等等,那不就是说明了 \(r={\Large\lfloor}\frac{n}{\lfloor\frac{n}{l}\rfloor}\Large\rfloor\) 吗!?

那么这样我们就顺利的得到了 \(r\) 的值并且可以求出当前块的所有数的和,也就是 \(S=(r-l+1)×\lfloor\frac{n}{l}\rfloor\)

\(\Large\mathcal{4,code}\)

int division_block(int n){
    int ans=0;
    for(int l=1,r;l<=n;l=r+1){
        r=n/(n/l);
        ans+=n/l*(r - l + 1);
    }
    return ans;
}

\(\Large\mathcal{5,example}\)
题目连接:[CQOI2007] 余数求和
思路:因为 \(a \mod b\) 可以转换为 \(a-\lfloor\frac{a}{b}\rfloor b\) 所以原式也就转化成了 \({\Large\sum_{i=1}^n} k-\lfloor\frac{k}{i}\rfloor i\) 可以发现 \(k\) 不会随着 \(i\) 的变化而变化,所以可以将 \(k\) 放在西格玛外面,\(nk-{\Large\sum_{i=1}^n}\lfloor\frac{k}{i}\rfloor i\) 于是在这么多奇妙转化下,我们可以发现式子最后不就变成了数论分块的模板吗!?所以直接套模板就行,细节看代码。

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,k,ans;
signed main(){
	cin>>n>>k;
	for(int l=1,r;l<=n;l=r+1){
		r=k/l==0?n:min(n,k/(k/l));
		ans+=(k/l)*(l+r)*(r-l+1)/2; 
	}
	cout<<n*k-ans<<endl;
	return 0;
}

\(\color{white}{代码有惊喜qwq}\)

标签:lfloor,frac,分块,数论,rfloor,Large,int,mathcal
From: https://www.cnblogs.com/chenzhekeai/p/18367040

相关文章

  • 分块 and 莫队
    分块一种暴力的数据结构,十分朴素的做法。能够处理许多问题。基础分块例\(1\):P3372【模板】线段树1经典老题,这次使用分块做法。我们将整个序列分为若干大小为\(T\)的块,记录其块的和和懒标记,对\([l,r]\)进行操作时,设左边界\(l\)位与块\(q\),左边界\(r\)位与块\(p\)......
  • Some 困难的数论
    1.离散对数就是在模\(p\)意义下求出\(\log_ab\)。等价于求出方程\(a^x\equivb\pmodm\)的解。其中的\(x\)就是\(\log_ab\)。当\(a\perpp\)时,BSGS算法可以求解出上面那个方程的解。具体的计算过程如下:我们设块长\(M\),并且\(x=AM-B\),那么\(a^{AM}\equiv......
  • 数论相关
    数论相关积性函数推论1:积性函数\(f\)一定满足\(f(1)=1\)。推论2:通过质数点值可以唯一确定完全积性函数,因为质数可以组成所有的数;通过所有\(p^k\)处的点值可以唯一确定积性函数,因为积性函数有前置条件\(n\botm\)所以要组合出有多个质因子\(p\)的数就需要\(p^k\)......
  • 线性结构查找(顺序、折半、分块)
    对于线性结构的查找,应掌握其查找的过程、构造判定树、分析平均查找长度等。一、顺序查找顺序查找又称线性查找,它对顺序表和链表都是适用的。对于顺序表,可通过数组下标递增来顺序扫描每个元素;对于链表,可通过指针next来依次扫描每个元素。顺序查找通常分为对一般的无......
  • 黑马Java零基础视频教程精华部分_15_基本查找/顺序查找、二分查找/折半查找、插值查找
    系列文章目录文章目录系列文章目录一、基本查找/顺序查找核心思想:从0索引开始挨个往后查找代码:练习:定义一个方法利用基本查找,查询某个元素在数组中的索引,数组包含重复数据。二、二分查找/折半查找核心思想:属于有序查找算法。用给定值先与中间结点比较,每次排除一半的......
  • 数据结构 分块 & 莫队
    分块一种优化暴力的思想。通常是将原数据划分成适当块(一般为\(\sqrt{n}\)),对每块数据进行预处理,进而达到比暴力更优的时间复杂度。划分确定块长后,一般需要开两个数组存储每一块的右边界与原数据所属块序号,更加方便后续操作。intsq=sqrt(n);for(inti=1;i<=sq;i++)ed[i]=n/......
  • 数论函数小记
    这篇文章是上了\(\rmyyc\)的课之后得到的一些心得和总结。高维点视角下的整除关系:我们可以将一个数\(x\)唯一分解为\(\prod_{i=1}^{+\infty}p_i^{x_i}\)的形式(其中\(p_i\)都是素数)。注意到每一种素数互不干扰,于是可以把每一种不同的素数看成立体空间的一维,把\(x\)......
  • leetcode数论(1232. 缀点成线)-几何
    前言经过前期的基础训练以及部分实战练习,粗略掌握了各种题型的解题思路。现阶段开始专项练习。数论包含最大公约数(>=2个数)、最大公约数性质、最小公倍数、区间范围质因素计数(最下间隔)、质因素分解、判断质数、平方根、立方根、互质、同余等等。描述给定一个数组 coor......
  • 数论总集
    卡特兰序列\(C_{k}(m,n)\)表示在网格中从\((0,0)\)走到\((m,n)\)时均不经过\(y=x+k\)的斜线即每时每刻满足\(y<x+k\)画图可得\(C_{k}(m,n)=\binom{n+m}{m}-\binom{n+m}{m+k}\)用法:任意前缀和不小于\(-x\)使用\(C_x\)(左括号是\(+1\))反射容斥学......
  • 数论——绝对素数、素数筛法、埃氏筛法、欧拉筛法、最大公约数
    绝对素数绝对素数是指一个素数在其十进制表示下,无论是从左向右读还是从右向左读,所得到的数仍然是素数。例如,13是一个素数,从右向左读是31,31也是素数,所以13是一个绝对素数。#include<iostream>#include<cmath>usingnamespacestd;boolisPrime(intnum){if(......