P2522 [HAOI2011]Problem b(莫反&整除分块)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2522 [HAOI2011]Problem b(莫反&整除分块)相关的知识,希望对你有一定的参考价值。
P2522 [HAOI2011]Problem b(莫反&整除分块)
∑ i = a b ∑ j = c d [ g c d ( i , j ) = k ] \\large \\sum\\limits_{i=a}^b \\sum\\limits_{j=c}^d [gcd(i,j)=k] i=a∑bj=c∑d[gcd(i,j)=k]
就是 f ( n , m , k ) = ∑ i = 1 n ∑ j = c m [ g c d ( i , j ) = k ] f(n,m,k)=\\large \\sum\\limits_{i=1}^n \\sum\\limits_{j=c}^m [gcd(i,j)=k] f(n,m,k)=i=1∑nj=c∑m[gcd(i,j)=k]
的变形。
直接容斥一下。
a n s = f ( b , d , k ) − f ( a − 1 , d , k ) − f ( a , c − 1 , k ) + f ( a − 1 , c − 1 , k ) ans=f(b,d,k)-f(a-1,d,k)-f(a,c-1,k)+f(a-1,c-1,k) ans=f(b,d,k)−f(a−1,d,k)−f(a,c−1,k)+f(a−1,c−1,k)
而 f ( n , m , k ) = ∑ d = 1 m i n ( n / k , m / k ) μ ( d ) ⌊ n k d ⌋ ⌊ m k d ⌋ \\large f(n,m,k)=\\sum\\limits_{d=1}^{min(n/k,m/k)} \\mu(d)\\lfloor\\dfrac{n}{kd}\\rfloor\\lfloor\\dfrac{m}{kd}\\rfloor f(n,m,k)=d=1∑min(n/k,m/k)μ(d)⌊kdn⌋⌊kdm⌋
线筛+预处理+整除分块,就可以秒了。
code
// Problem: P3327 [SDOI2015]约数个数和
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3327
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Date: 2021-07-07 19:25:15
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=5e4+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
}
int mu[N],p[N],cnt;
ll pre[N];
bitset<N>vis;
void init(int n){
vis[1]=mu[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]) p[++cnt]=i,mu[i]=-1;
for(int j=1;j<=cnt&&i*p[j]<=n;j++){
vis[i*p[j]]=1;
if(i%p[j]==0){
break;
}
mu[i*p[j]]=mu[i]*mu[p[j]];
}
}
for(int i=1;i<=n;i++) mu[i]+=mu[i-1];
}
int a,b,c,d,k;
ll fun(int n,int m){
n/=k,m/=k;
ll s=0;
for(int l=1,r;l<=min(n,m);l=r+1){
r=min(n/(n/l),m/(m/l));
s+=1LL*(mu[r]-mu[l-1])*(n/l)*(m/l);
}
return s;
}
int main(){
int t;scanf("%d",&t);
init(N-1);
while(t--){
scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
printf("%lld\\n",fun(b,d)-fun(a-1,d)-fun(b,c-1)+fun(a-1,c-1));
}
return 0;
}
以上是关于P2522 [HAOI2011]Problem b(莫反&整除分块)的主要内容,如果未能解决你的问题,请参考以下文章