1. 程式人生 > >Problem b【HAOI2011】【莫比烏斯反演進階】

Problem b【HAOI2011】【莫比烏斯反演進階】

傳送門:https://www.luogu.org/problemnew/show/P2522

這道題,,其實就是zap-queries 的進階版

在其基礎上加了個差分,其他隻字未變

上程式碼

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define in read()
using namespace std;

inline int in{
	int cnt=0,f=1; char ch=0;
	while(!isdigit(ch)){
		ch=getchar();
		if(ch=='-')f=-1;
	}
	while(isdigit(ch)){
		cnt=cnt*10+ch-48;
		ch=getchar();
	}
	return cnt*f;
}
#define N 50003
int mu[N],prim[N],cnt,vis[N];
long long sum[N];
inline void mumu(int n){
	mu[1]=1;
	for(register int i=2;i<=n;i++){
		if(!vis[i]){
			prim[++cnt]=i;
			mu[i]=-1;
		}
		for(register int j=1;j<=cnt&&prim[j]*i<=n;j++){
			vis[prim[j]*i]=1;
			if(i%prim[j]==0)break;
			else mu[prim[j]*i]=-mu[i];
		}
	}
	for(register int i=1;i<=n;i++)sum[i]=sum[i-1]+(long long)mu[i];
}int a,b,c,d,k;
inline long long query(int a,int b){
	if(a>b)swap(a,b);long long ans=0;
	for(register int l=1,r;l<=a;l=r+1){
		r=min(a/(a/l),b/(b/l));
		ans+=(1ll*a/(1ll*l*k))*(1ll*b/(1ll*l*k))*(sum[r]-sum[l-1]); 
	}
	return ans;
}
int main(){
	int t=in;mumu(N);
	while(t--){
		a=in;b=in;c=in;d=in;k=in;
		printf("%lld\n",query(b,d)-query(b,c-1)-query(a-1,d)+query(a-1,c-1));
	}
	return 0;
} 

注意1ll的重要性,,longlong嘛畢竟。

公式推法和上次一樣。

另外,,本題如果不開O2會T6個點。。ovo