BZOJ1101 Zap

El blogger ha vuelto al artículo, este es el título de la primera función de Mobius.

Ideas

Preguntemos cuántos pares \ (x \ leq a, y \ leq b \) \ ((x, y) \) satisfar \ (\ gcd (x, y) = d \) es
equivalente a
cuántos \ ((x, y) \) satisface \ (x \ leq x / d, y \ leq b / d \) para que \ (\ gcd (x, y) = 1 \)
se establezca en \ (d (a, b , k) \) significa cuántos pares de \ ((x, y) \) satisfacen \ (x \ leq a, y \ leq b \) y \ (k | gcd (a, b) \)

\ [d (a, b, k) = \ left \ lfloor \ dfrac {a} {k} \ right \ rfloor * \ left \ lfloor \ dfrac {b} {k} \ right \ rfloor \]

Esta fórmula se puede optimizar dividiendo por bloques .
Deje que \ (f (a, b) \) indique cuántos pares \ ((x, y) \) satisfacen \ (x \ leq a, y \ leq b \) y \ (mcd (x, y) = 1 \)
Según el principio de tolerancia y exclusión

\ [f (a, b) = \ mu (i) * d (a, b, i) \]

El significado aquí es probablemente que no hay restricciones en el número de duales como \ (d (a, b, 1) \) , y luego restando \ (mcd (x, y) \) es \ (2,3,5 ...... \ ) , El número de dobles en múltiplos, y luego vuelve a agregar \ (mcd (x, y) \) que es tanto \ (2 \) como múltiplos de \ (3 \) ...

\(código\)

/*
@ author:pyyyyyy
-----思路------
-----debug-------
memset(miu,1,sizeof(miu))不是把miu全赋值成1,我傻了 
*/
#include<bits/stdc++.h>
using namespace std;
const int N=50041;
int T,a,b,d;
int miu[N],v[N];
void prime(int n)
{
	for(int i=2;i<=n;++i)
	{
		if(v[i]) continue;
		miu[i]=-1;
		for(int j=2*i;j<=n;j+=i)
		{
			v[j]=1;
			if((j/i)%i==0) miu[j]=0;
			else miu[j]*=-1;
		}
	}
}
int Zap(){
	a/=d,b/=d;
	int ans=0;
	if(a>b) swap(a,b);
	for(int l=1,r;l<=a;l=r+1)
	{
		r=min(a/(a/l),b/(b/l));
		ans+=(miu[r]-miu[l-1])*(a/l)*(b/l);
	}
	return ans;
}
int main()
{
	for(int i=1;i<N;++i) miu[i]=1;
	prime(N);
	for(int i=1;i<N;++i) miu[i]+=miu[i-1];
	cin>>T;
	while(T--)
	{
		cin>>a>>b>>d;
		cout<<Zap()<<'\n';	
	}	
	return 0;
}

Supongo que te gusta

Origin www.cnblogs.com/pyyyyyy/p/12752050.html
Recomendado
Clasificación