下面给出部分分做法和满分做法

有一些奇妙的方法可以拿到同样多的分数,本蒟蒻只能介绍几种常见的做法

如果您想拿18分左右,需要了解:质因数分解

如果您想拿30分左右,需要了解:一种较快的筛法

如果您想拿70分左右,需要了解:莫比乌斯反演+杜教筛+整除分块+容斥

如果您想拿100分,需要了解:线性筛+杜教筛+莫比乌斯函数+狄利克雷卷积+推式子+微积分+整除分块

这时候如果您还想做这道题的话。。。


18分做法

首先N=1 时,就是求不超过 M的完全平方数有多少个,直接输出\(\lfloor \sqrt{M} \rfloor\)就好啦。

将 a中的最大完全平方因子除去以后所得的数记为 A

将 b中的最大完全平方因子除去以后所得的数记为 B

因为ab是完全平方数,所以AB是完全平方数,因为A,B只含一次方的质因数,所以A=B

枚举a,由于 a/A是 a的约数中最大的完全平方数,可以枚举不超过a 的所有完全平方数求出 a的最大平方约数(或把a 分解质因数)来计算出A

b一定是A的完全平方数倍,A固定时b的取值一共有 \(\lfloor \sqrt{M / A} \rfloor\)个。

时间复杂度:O((N⋅ $\sqrt{N} $)

30分做法

枚举A,计算有多少组对应的有序数对(a,b)。

A只能取不包含平方因子的数,只需让 a/A,b/A为完全平方数,并且 \(1 \leq a \leq N, 1 \leq b \leq M\) 。

当 A确定时,a,b可以取的值的即分别不超过 \(\lfloor N / A\rfloor\) 和 \(\lfloor M / A \rfloor\) 的完全平方数,即分别有 \(\big\lfloor\sqrt{\lfloor N / A \rfloor}\big\rfloor\)和 \(\big\lfloor\sqrt{\lfloor M / A \rfloor}\big\rfloor\)种取值

A即不超过 \(\min(N,M)\)的不包含平方因子的数。可以用筛法求出来

把所有(大于1的)完全平方数的倍数筛掉,剩下的就是不包含平方因子的数。

时间复杂度是O( \(\min(N, M)\))

然后枚举 A,将对应的 a和b 的数量乘起来(即 \(\big\lfloor\sqrt{\lfloor N / d \rfloor}\big\rfloor \times \big\lfloor\sqrt{\lfloor M / d \rfloor}\big\rfloor\))计入答案。

时间复杂度: O(\(\min(N, M))\))。

大约70分的做法

不妨设 \(N \leq M\)

考虑枚举数对 a和 b的最大公约数,设为d。则a/d与b/d 必须是互质的完全平方数,于是我们可以统计\([1, \lfloor \sqrt{\frac N d} \rfloor]\)与\([1, \lfloor \sqrt{\frac M d} \rfloor]\)中互质数的对数。

答案就是 \(\sum _d \sum _i ^ {\lfloor \sqrt{\frac N d} \rfloor} \sum _j ^ {\lfloor \sqrt{\frac M d} \rfloor}[ \gcd (i, j) = 1]\)

是一个经典的莫比乌斯反演问题;于是我们在\(\sqrt{N}\)范围线性筛,再对d分块处理。时间O(\(\sqrt{N}\cdot 大常数\))

优秀的话可以拿到95分


(开始乱搞)

大约70分做法(懒得写那么多惹,有的地方默认M,N同级)

根据上文易知答案 =\(\sum_{x=1}^{\min(N, M)} \mu^2(x) \cdot \big\lfloor\sqrt{\lfloor N / x \rfloor}\big\rfloor \cdot \big\lfloor\sqrt{\lfloor M / x \rfloor}\big\rfloor\)

根据容斥原理,\(\mu^2\)的前缀和 $ \sum_{x=1}^{n} \mu^2(x) = \sum_{i=1}^{\lfloor \sqrt{n} \rfloor} \mu(i) \cdot \lfloor \frac{n}{i^2} \rfloor $

你发现$\lfloor\frac{n}{i^2} \rfloor $可以整除分块

O(\(\n^{1/3}\))的时间复杂度内计算

可以整除分块\(\big\lfloor\sqrt{\lfloor N / x \rfloor}\big\rfloor \cdot \big\lfloor\sqrt{\lfloor M / x \rfloor}\big\rfloor\)

用线性筛预处理\(\sqrt{N}\) 以内的\(\mu\) 的前缀和,\(\mu^2\)的前缀和

\(\big\lfloor\sqrt{\lfloor N / x \rfloor}\big\rfloor\)一共改变了 \(O(N^{1/3})\)次值,所以 \(\big\lfloor\sqrt{\lfloor N / x \rfloor} \big\rfloor \cdot \big\lfloor\sqrt{\lfloor M / x \rfloor}\big\rfloor\) 一共改变了 \(O(\min(M^{1/3}+N^{1/3}, min(M,N)))\) 次值

为什么呢?

张老师给出的证明:

如果\(\min(M^{1/3}+N^{1/3}, min(M,N))\)大约是我们需要计算 \(\mu^2\)的前缀和的次数。

如果计算 \(\mu^2\)的前缀和的复杂度为 \(O(N^{1/3})\)

这个算法的时间复杂度约为\(O(N^{1/3} \cdot min(M^{1/3}+N^{1/3}, min(M+N)\big) \big)\)

感觉很虚,优化得和没有优化一样

仔细计算时间:

对\(n=1\) 到 \(O(\min(M^{1/3}+N^{1/3}, min(M+N)))\)计算 \(\sum_{x=1}^{n} \mu^2(x)\)

时间复杂度约为 \(O\left(\int_1^{\min(M^{1/3},N)} x^{1/3} \mathrm{d}x\right) = O\left(\min(M^{4/9}, N^{4/3})\right)\)

然后对 $\sqrt{M / n} = \sqrt{M / N} \(到\) M^{1/3}

$ 计算 \(\sum_{x=1}^{n} \mu^2(x)\)

时间复杂度为 \(O\left(\int_{\sqrt{M/N}}^{M^{1/3}} M^{1/3}x^{-2/3} \mathrm{d}x\right) = O\left(\min(M^{4/9},M^{1/2}) - M^{1/2}N^{-1/6}\right)\)

所以,当 \(\max(N,M) > \left(\min(N,M)\right)^3\)

时,时间复杂度为 \(O\left(\left(\min(N,M)\right)^{4/3}\right)\)

而且因为一部分\(\mu^2\)已经预处理了,所以实际的时间复杂度还会小一些


大约90分做法

(题解太长,我有点不想写了)

发现上一个的算法的问题在于空间

令线性筛预处理范围 \(S < \sqrt{N}\)

记 \(\sum\mu(n) = \sum_{x=1}^{n} \mu(x), \sum\mu^2(n) = \sum_{x=1}^{n} \mu^2(x)\)

我们需要计算这些$ \mu^2$的前缀和: \(\sum\mu^2(N)\)

\(\sum\mu^2\left(\left\lfloor \frac{M}{\left(\lfloor\sqrt{M / N}\rfloor + 1\right)^2} \right\rfloor\right),\)

$ \sum\mu^2\left(\left\lfloor \frac{M}{\left(\lfloor\sqrt{M / N}\rfloor + 2\right)^2} \right\rfloor\right), $

\(\dots\)

和形如 \(\sum\mu^2(\lfloor \frac{N}{\dots} \rfloor)\) 的前缀和

计算 \(\mu^2\)的前缀和的过程: \(\sum\mu^2(n) = \sum_{i=1}^{\lfloor \sqrt{n} \rfloor} \mu(i) \cdot \lfloor \frac{n}{i^2} \rfloor\)

所以在计算 \(\sum\mu^2(n)\)时需要求 \(\sum\mu(\lfloor \sqrt{n} \rfloor), \sum\mu(\lfloor \sqrt{n / 2} \rfloor), \sum\mu(\lfloor \sqrt{n / 3} \rfloor), \dots\)

计算\(\mu\)的前缀和的过程(由狄利克雷卷积可求出):\(\sum\mu(n) = 1 - \sum_{i=2}^{n} \sum\mu(\lfloor n / i \rfloor)\)

如果一次性求出所有满足 $\lfloor n / i \rfloor > S \(的\) \sum\mu(\lfloor n / i \rfloor)$(i为正整数),所需时间复杂度为 \(O\left(\int_{1}^{n / S} \sqrt{n / x} \mathrm{d}x\right) = O(n \cdot S^{-1/2})\)

杜教筛 \(O(n^{2/3})\)的时间复杂度就是 \(O(n \cdot S^{-1/2} + S)\)

根据上述信息,所有要计算的\(\mu\)的前缀和:

\(\mathrm{for}_{i=\lfloor \sqrt{M/N} \rfloor}^{\lfloor \sqrt{M}/S \rfloor} \mathrm{for}_{j=1}^{\lfloor M / (i^2S^2) \rfloor} \sum\mu(\lfloor \frac{\sqrt{M}}{i \sqrt{j}}\rfloor)\)

交换一下循环顺序,可以发现只需计算所有满足 \(\lfloor \frac{M/j}{i} \rfloor > S\) 的 \(\sum\mu(\lfloor \frac{M/j}{i} \rfloor)\)

时间复杂度为 \(O\left(\int_1^{M / S^2} \sqrt{M / x} \cdot S^{-1/2} \mathrm{d}x\right) = O(M \cdot S^{-3/2})\)

这样我们可以取 \(S = \left(\max(N,M)\right)^{3/7} < 9000000\)

做到 \(O\left( \left(\max(N,M)\right)^{3/7}\right)\)

的总时间复杂度。

得分: 95~100 分。

意思是分析了这么久,优化来优化去,如果写的丑的话,还是没有100分

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; const int N=20000031; bool vis[N];
int p[N /10],mu[N];
ll mu2[N]; int maxn=0; void init(){
mu[1]=1;
for(int i=2,tot=0;i<=maxn;i++){
if(!vis[i]) p[tot++]=i,mu[i]=-1;
for(int j=0;j<tot&&i*p[j]<=maxn;j++){
vis[i*p[j]]=1;
if(i%p[j]) mu[i*p[j]]=-mu[i];
else{
mu[i*p[j]] = 0;
break;
}
}
}
for(int i=1;i<=maxn;++i) mu2[i]=mu2[i-1]+(mu[i]!=0),mu[i]+=mu[i-1];
} ll m,n; inline ll squ(ll x){return x*x;}
map<ll,ll> qq;
ll g(ll x){
if(x<=maxn) return mu[x];
auto it=qq.find(x);
if(it!=qq.end()) return it->second;
ll ans=1;
for (ll i=2,j=0;i<=x;i=j+1) ans-=g(x/i)*((j=x/(x/i))-i+1);
return qq[x]=ans;
} ll f(ll x){
if(x<=maxn) return mu2[x];
ll ans=0,i=1,t=0,a=0,b=0;
for(;i*i*i<=x;++i)t=x/squ(i),ans+=t*((a=mu[i])-b),b=a;
for(ans-=(t=x/squ(i))*b;t;--t)ans+=g(sqrt(x/t));
return ans;
} int main(){
scanf("%lld%lld",&n,&m);
if (n>m) swap(n,m);
maxn=min((ll)(pow(m,3/7.0)),n);
init();
ll ans=0,x=0,y=0,a=0,b=0;
for(ll i=1,j=0;i<=n;i=j+1) j=min(n/squ(x=sqrt(n/i)),m/squ(y=sqrt(m/i))),ans+=x*y*((a=f(j))-b),b=a;
printf("%lld\n",ans);
}

#509. 「LibreOJ NOI Round #1」动态几何问题的更多相关文章

  1. #510. 「LibreOJ NOI Round #1」动态几何问题

    题目: 题解: 几何部分,先证明一下 \(KX = \sqrt{a},YL = \sqrt{b}\) 设左侧的圆心为 \(O\) ,连接 \(OK\) ,我们有 \(OK = r\). 然后有 \(r ...

  2. 「LibreOJ NOI Round #2」不等关系

    「LibreOJ NOI Round #2」不等关系 解题思路 令 \(F(k)\) 为恰好有 \(k\) 个大于号不满足的答案,\(G(k)\) 表示钦点了 \(k\) 个大于号不满足,剩下随便填的 ...

  3. LibreOJ #507. 「LibreOJ NOI Round #1」接竹竿

    二次联通门 : LibreOJ #507. 「LibreOJ NOI Round #1」接竹竿 /* LibreOJ #507. 「LibreOJ NOI Round #1」接竹竿 dp 记录一下前驱 ...

  4. 「LibreOJ NOI Round #1」验题

    麻烦的动态DP写了2天 简化题意:给树,求比给定独立集字典序大k的独立集是哪一个 主要思路: k排名都是类似二分的按位确定过程. 字典序比较本质是LCP下一位,故枚举LCP,看多出来了多少个独立集,然 ...

  5. #507. 「LibreOJ NOI Round #1」接竹竿 dp

    题目: 题解: 我们考虑把每对花色相同的牌看作区间. 那么如果我们设 \(f_i\) 表示决策在 \([1,i]\) 内的最优答案. 那么有 \(f_i = max\{max\{(f_{j-1}+\s ...

  6. LOJ#510. 「LibreOJ NOI Round #1」北校门外的回忆(线段树)

    题面 传送门 题解 感谢\(@M\_sea\)的代码我总算看懂题解了-- 这个操作的本质就是每次把\(x\)的\(k\)进制最低位乘\(2\)并进位,根据基本同余芝士如果\(k\)是奇数那么最低位永远 ...

  7. LOJ 510: 「LibreOJ NOI Round #1」北校门外的回忆

    题目传送门:LOJ #510. 题意简述: 给出一个在 \(K\) 进制下的树状数组,但是它的实现有问题. 形式化地说,令 \(\mathrm{lowbit}(x)\) 为在 \(K\) 进制下的 \ ...

  8. 「LibreOJ NOI Round #2」单枪匹马

    嘟嘟嘟 这题没卡带一个\(log\)的,那么就很水了. 然后我因为好长时间没写矩阵优化dp,就只敲了一个暴力分--看来复习还是很关键的啊. 这个函数显然是从后往前递推的,那么令第\(i\)位的分子分母 ...

  9. LOJ575. 「LibreOJ NOI Round #2」不等关系 [容斥,分治FFT]

    LOJ 思路 发现既有大于又有小于比较难办,使用容斥,把大于改成任意减去小于的. 于是最后的串就长成这样:<<?<?<??<<<?<.我们把一段连续的& ...

随机推荐

  1. MySQL之慢查询日志和通用查询

    MySQL中的日志包括:错误日志.二进制日志.通用查询日志.慢查询日志等等.这里主要介绍下比较常用的两个功能:通用查询日志和慢查询日志. 1.通用查询日志:记录建立的客户端连接和执行的语句. 2.慢查 ...

  2. php之IP

    常用的获取客户端的IP地址的方法: 1) function getRemoteIp(){ if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){ $ip = $_SE ...

  3. 【Python3练习题 015】 一球从100米高度自由落下,每次落地后反跳回原高度的一半,再落下。求它在第10次落地时,共经过多少米?第10次反弹多高?

    a = [100]  #每个‘反弹落地’过程经过的路程,第1次只有落地(100米) h = 100  #每个‘反弹落地’过程,反弹的高度,第1次为100米 print('第1次从%s米高落地,走过%s ...

  4. 【Python3练习题 014】 一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如6=1+2+3。编程找出1000以内的所有完数。

    a.b只要数字a能被数字b整除,不论b是不是质数,都算是a的因子.比如:8的质因子是 2, 2, 2,但8的因子就包括 1,2,4. import math   for i in range(2, 1 ...

  5. 关于百度地图API和jqGrid踩到的坑

    1.百度地图重新标记问题 var map = new BMap.Map("map"); ...... var marker = new BMap.Marker(point); // ...

  6. 在linux上安装spark详细步骤

    在linux上安装spark ,前提要部署了hadoop,并且安装了scala. 提君博客原创 对应版本 >>提君博客原创  http://www.cnblogs.com/tijun/   ...

  7. C# Note26: [MethodImpl(MethodImplOptions.Synchronized)]与lock机制

    在进行.NET开发时,经常会遇见如何保持线程同步的情况.在众多的线程同步的可选方式中,加锁无疑是最为常用的.如果仅仅是基于方法级别的线程同步,使用System.Runtime.CompilerServ ...

  8. Codeforces 1154C Gourmet Cat

    题目链接:http://codeforces.com/problemset/problem/1154/C 题目大意: 主人有一只猫.周一&周四&周日:吃鱼周二&周六:吃兔子周三 ...

  9. java学习之—递归实现变位字

    /** * 递归实现变位字 * Create by Administrator * 2018/6/20 0020 * 上午 10:23 **/ public class AnagramApp { st ...

  10. Python——组图Canvas控制参数

    一.参数说明 background(bg) : 背景色; foreground(fg): 前景色; borderwidth :组件边框宽度: width  : 组件宽度: height  : 高度; ...