数论分块

数论分块

定义

用于求解形如

\[\sum_{i=1}^{n}f(i)*g(\left \lfloor \frac{k}{i}\right\rfloor) \]

的和式,通常被称为整除分块

当能用O(1)的时间求出

\[\sum_{i=1}^{n}f(i) \]

数论分块便能在O(\(\sqrt n\))的时间内求出上式

结论

\[\forall k,l\in N^+,(l\leq n)\\\exists r,(1\leq l\leq r \leq n),使得 \left \lfloor \frac{k}{l} \right \rfloor =\left \lfloor \frac{k}{r} \right \rfloor \\ r_{max}=\left \lfloor \frac{k}{\left \lfloor \frac{k}{l} \right \rfloor} \right \rfloor\\ \]

证明

\[\forall x\in N^+,设temp=\left\lfloor\frac{k}{x}\right\rfloor\\ \therefore k=x*temp+r,(0\leq r<x)\\ \therefore k \ge x*temp\\ \therefore x\leq \frac{k}{temp}\\ 又\because x\in N^+\\ \therefore x\leq \left\lfloor \frac{k}{temp} \right\rfloor \]

应用

1.求\(\sum_{i=1}^{n} \left\lfloor \frac{n}{i} \right \rfloor\)

int solve(int n){
    int res=0;
    int l=1,r=0;
    while(l<=n){
        int temp=n/l;
        r=n/temp;
        res+=(r-l+1)*temp;
        l=r+1;
    }
    return res;
}

2.P2261 [CQOI2007] 余数求和

给出正整数 \(n\)\(k\),请计算

\[G(n,k)=\sum_{i=1}^{n}k\bmod i \]

分析

\[\because k\bmod i=k-\left\lfloor\frac{k}{i}\right\rfloor*i\\ \therefore \sum_{i=1}^{n}k\bmod i=\sum_{i=1}^{n}k-\left\lfloor\frac{k}{i}\right\rfloor*i\\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ =n*k-\sum_{i=1}^{n}\left\lfloor\frac{k}{i}\right\rfloor*i\\ \]

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,k,ans;
ll solve(){
    ll res=0;
    ll l=1,r=0;
    while(l<=n){
        ll temp=k/l;
        if(temp==0)r=n;//注意k可能小于n或大于n
        else r=min(k/temp,n);
        ll sum=(r+l)*(r-l+1)/2;
        res+=sum*temp;
        l=r+1;
    }
    return res;
}
int main(){
    scanf("%lld%lld",&n,&k);
    ans=k*n-solve();
    printf("%lld",ans);
	return 0;
}
posted @ 2025-10-23 23:07  R-99Player  阅读(3)  评论(0)    收藏  举报