【长期】数论题

题单:

  1. 数论分块、莫比乌斯反演与筛法
  2. 莫比乌斯反演
  3. 数论1数论2

整除分块 UVA11526

i=1nni

注意到当 i=l 时,有 val=nl。假设当 i=r 时值仍然为 val,则有 val=nrvalnr<val+1rnvalr 为整数。

因此,当 linnlval 相等。可以证明,这样的值不超过 n 个,因此时间复杂度 O(n)


P2261 余数求和

i=1nkmodi,  n,k109

本题考查取模运算的本质。kmodi 相当于 kki×i,因此本题式子可以化为:

i=1nkmodi=i=1nkki×i=nki=1nki×i

这同样可以使用整除分块求解,辅以等差数列求和即可,即每次累加

i=lrval×i=val×i=lri=val×(l+r)(rl+1)2


清华集训2012 模积和·改

i=1nj=1m(n wod i)(m wod j)[ij]   (wod k)

N wod p={0,pNp(Nmodp),otherwise

同样地,我们来看 wod 运算的本质。实际上 Nwod i=Ni×iN。不妨设 nm,则原式可以化为

i=1n(n wod i)j=1m(m wod j) [ij]

=i=1n(n wod i)j=1m(m wod j)i=1n(n wod i)(m wod i)

=i=1n(ni×in)j=1m(mj×jm)i=1n(ni×in)(mi×im)

我们将前后两部分分别记为 A,D 并分开计算:

A=((i=1nni×i)n2)((j=1mmj×j)m2)

其中上取整同样可以用整除分块在根号的时间复杂度下计算:

val=nlnr=val  val1<nrvalr<nval1

现在需要对 val1 分类讨论。

  1. 如果 val=1,那么 r=n,即直接取到右端点;
  2. 如果 (val1)|n,那么 r=nval11
  3. 否则 r=nval1

An,m 两部分分开计算即可,时间复杂度 O(n)

D=n2m+i=1nnimi×i2n×i=1nmi×im×i=1nni×i

这个式子同样可以用整除分块计算,其中还需要平方和公式的前缀和做差

i=1ni2=n(n+1)(2n+1)6

由于在模意义下计算,需要算出 2,6 等的逆元,在不保证模数是质数的情况下使用 exgcd 即可。最后输出时,由于是 wod k,等价于 (mod - ans%mod) % mod 语句,中途使用正常的 %mod 即可。

inline ll work(ll lim, ll num) {
ll res = 0;
for(ll l = 1, r = 1; l <= lim; l = r + 1) {
ll val = ceil(num * 1.0 / l);
if(val == 1) r = lim;
else if(num % (val - 1) == 0) r = num / (val - 1) - 1;
else r = num / (val - 1);
r = min(r, lim);
ll sum = ((inv2 * (l + r) % mod) * (r - l + 1) % mod);
res = (res + val * sum % mod) % mod;
}
return res;
}
inline ll Square(ll x) {return (((inv6 * x % mod) * (x + 1) % mod) * (2 * x + 1)) % mod;}
inline ll rSum(ll x, ll y) {return ((Square(y) - Square(x - 1)) % mod + mod) % mod;}
inline void solve() {
read(T);
while(T --) {
read(n); read(m); read(mod); if(n > m) n ^= m ^= n ^= m; inv2 = inv(2); inv6 = inv(6);
ll ans = 0; ll n2 = ((n % mod) * n % mod), m2 = ((m % mod) * m % mod);
ll M1 = ((work(n, n) - n2) % mod + mod) % mod;
ll M2 = ((work(m, m) - m2) % mod + mod) % mod;
ans = M1 * M2 % mod;
ll D = n2 * m % mod;
D = ((D - n * work(n, m) % mod) % mod + mod) % mod;
D = ((D - m * work(n, n) % mod) % mod + mod) % mod;
ll res = 0;
for(ll l = 1, r = 1; l <= n; l = r + 1) {
ll val1 = ceil(n * 1.0 / l), val2 = ceil(m * 1.0 / l);
ll rn = 0, rm = 0;
if(val1 == 1) rn = n;
else if(n % (val1 - 1) == 0) rn = n / (val1 - 1) - 1;
else rn = n / (val1 - 1);
if(val2 == 1) rm = n;
else if(m % (val2 - 1) == 0) rm = m / (val2 - 1) - 1;
else rm = m / (val2 - 1);
rm = min(rm, n);
r = min(rn, rm); ll sum = rSum(l, r);
res = (res + (val1 * val2 % mod) * sum % mod) % mod;
}
D = (D + res) % mod;
ans = ((ans - D) % mod + mod) % mod; ans = (mod - ans) % mod;
writeln(ans);
}
}

P3935 约数个数和
题目中的 f(n)=τ(n) 表示约数个数,因此此题求得是

i=lrτ(i)(mod998244353)

枚举约数,并利用前缀和做差计算区间和即可,因此下面计算前缀和。

i=1nτ(i)=d=1ni=1n[gcd(i,d)=d]=d=1ni=1n/d[gcd(i,1)=1]=d=1nnd

用整除分块计算即可,时间复杂度 O(n)


P2158 仪仗队

转化成平面直角坐标系,除了 (1,0),(0,1) 两个点之外,其余点 (i,j),i,j[1,N) 有连线当且仅当 gcd(i,j)=1,否则会被点 (igcd(i,j),jgcd(i,j)) 挡住。

因此,答案为

2+i=1n1j=1n1[gcd(i,j)=1]=3+2i=2n1j<i[gcd(i,j)=1]=3+2i=2n1φ(i)=1+2i=1n1φ(i)


Divisors

这道题是一道筛法练习题。

题目中要求 τ(n)=p1×p2,定义 ω(n) 表示去重前 n 的质因数个数,lpf(n) 表示 n 的最小质因数大小,即 least prime factor

这两个函数都可以在线性筛的时候计算,其中

ω(i×primej)=ω(i)+1

lpf(i×primej)=min(primej,lpf(i))

这样计算出 ω 的问题在于当 i=primejω(p2)=2,所以判断的条件是 ω(τ(x))=2  τ(x)lpf(τ(x))2

inline void init(int MAX) {
vis[1] = vis[0] = 1;
tau[1] = 1, w[1] = lpf[1] = 0;
rep(i, 2, MAX) {
if(!vis[i]) prime[++cnt] = i, tau[i] = 2, w[i] = 1, lpf[i] = i;
for(int j = 1; j <= cnt && i * prime[j] <= MAX; j ++) {
w[i * prime[j]] = w[i] + 1;
vis[i * prime[j]] = 1;
lpf[i * prime[j]] = min(lpf[i], prime[j]);
if(i % prime[j] == 0) {
tau[i * prime[j]] = tau[i] * 2 - tau[i / prime[j]];
break;
}
tau[i * prime[j]] = tau[i] * 2;
}
}
}
int main () {
init(1000000), int k = 0;
rep(i, 1, 1000000) {
if(w[tau[i]] == 2 && tau[i] != lpf[tau[i]] * lpf[tau[i]])
if(++k == 9) k = 0, writeln(i);
}
return 0;
}
posted @   Mars_Dingdang  阅读(88)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示