【题意】于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数。n,a,b,c,d,k<=50000。

【算法】数论(莫比乌斯反演)

【题解】差分转化为询问有多少数对(x,y)满足x,y互素,1<=x<=n/k,1<=y<=m/k。

令f[x]表示gcd(a,b)=x的数对个数,F[x]表示满足 x | gcd(a,b) 的数对个数,则F[x]=Σx|df(d)。

易得F[x]=(n/x)*(m/x),那么根据莫比乌斯反演定理,f(x)=Σx|dμ(d/n)*F(d)=Σx|dμ(d/n)*(n/d)*(m/d)。

当x=1时,f(1)=Σμ(d)*(n/d)*(m/d),d=1~min(n,m),单次询问复杂度O(n)。

继续优化,n/d至多只有2*√n个取值,只要枚举这些取值后运用μ的前缀和(预处理)快速计算。

具体方法是:当前取值为n/i时,最小为i,最大为pos=n/(n/i),这m/(m/i)取min即可。

复杂度O(n√n)。

#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=;
int miu[maxn],prime[maxn],tot,s[maxn],n;
bool mark[maxn];
void pre(int n){
miu[]=;
for(int i=;i<=n;i++){
if(!mark[i])miu[i]=-,prime[++tot]=i;
for(int j=;j<=tot&&i*prime[j]<=n;j++){
mark[i*prime[j]]=;
miu[i*prime[j]]=-miu[i];
if(i%prime[j]==){miu[i*prime[j]]=;break;}
}
}
for(int i=;i<=n;i++)s[i]=s[i-]+miu[i];
}
ll solve(int n,int m){
ll ans=;int pos=;
for(int i=;i<=min(n,m);i=pos+){
pos=min(n/(n/i),m/(m/i));
ans+=1ll*(s[pos]-s[i-])*(n/i)*(m/i);
}
return ans;
}
int main(){
scanf("%d",&n);
pre();
for(int i=;i<=n;i++){
int a,b,c,d,k;
scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
a--;c--;a/=k;b/=k;c/=k;d/=k;
printf("%lld\n",solve(b,d)-solve(b,c)-solve(a,d)+solve(a,c));
}
return ;
}

尝试从套路的角度来推导ans=Σx|dμ(d/n)*(n/d)*(m/d)

★当x=1时,Σd|xμ(x)=1。所以gcd(a,b)=1等价于Σd|a&&d|bμ(d)。——①

$$ans=\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j)=k]$$

(i,j)=k等价于(i/k,j/k)=1可以得到:——②

$$ans=\sum_{i=1}^{\frac{n}{k}}\sum_{j=1}^{\frac{m}{k}}[gcd(i,j)=1]$$

下一步代入经典gcd转μ,得到:

$$ans=\sum_{i=1}^{\frac{n}{k}}\sum_{j=1}^{\frac{m}{k}}\sum_{d|i\cap d|j}\mu (d)$$

套路化地改为枚举gcd,得到:——③

$$ans=\sum_{d=1}^{min(\frac{n}{k},\frac{m}{k})}\mu (d)\sum_{i=1}^{\frac{n}{k}}\sum_{j=1}^{\frac{m}{k}}[d|i\cap d|j]$$

最后部分满足条件的数对都可以除以d,就可以压缩上标直接计算了,即:——④

$$ans=\sum_{d=1}^{min(\frac{n}{k},\frac{m}{k})}\mu (d)\left \lfloor \frac{n}{kd} \right \rfloor\left \lfloor \frac{m}{kd} \right \rfloor$$

最新文章

  1. Linux碎碎念
  2. SpringMVC @Value取值(取properties属性文件的属性值)
  3. delete错误
  4. uva 11107 Life Forms
  5. Java的序列化与反序列化(一):初识
  6. 宣布发布全新的 Windows Azure 缓存预览版
  7. NYOJ 118 路方案(第二小的跨越)
  8. 如何编译Apache Hadoop2.2.0源代码
  9. 关于layer的坑
  10. HashSet&lt;T&gt;的妙用
  11. Spring使用 --- 基本概念(一):DI,依赖注入
  12. Solve Error: &quot;errcode&quot;: 40016, &quot;errmsg&quot;: &quot;invalid button size hint&quot;
  13. 百战程序员——JDBC
  14. Hdoj 1253.胜利大逃亡 题解
  15. windows server 禁用智能卡服务的步骤
  16. [macOS] PHP双版本,5.6跟7.1
  17. vue相关操作命令
  18. 吴裕雄 python深度学习与实践(5)
  19. 挂载报错:“/dev/vda1 is apparently in use by the system;”
  20. 关于NLPIR应用在KETTLE中的探索

热门文章

  1. HTML5+规范:Webview的使用详解
  2. Windows Forms编程实战学习:第二章 欢迎使用Visual Studio
  3. C#高级编程 (第六版) 学习 第六章:运算符和类型强制转换
  4. ADO.NET DBHelper 类库
  5. Mybatis 映射关系
  6. 第187天:js基础---常见的Bom对象
  7. HDU4802_GPA
  8. Now or later UVALive - 3211(2-SAT 最小值最大化)
  9. MySQL主键和外键使用及说明
  10. 【Luogu3676】小清新数据结构题(动态点分治)