Square-free integers SPOJ - SQFREE(容斥,完全平方数)

思路:要求1到n不能被任意完全平方数整除的数,正难则反,等价求n减去1到n是完全平方数倍数的数的个数,然后容斥下。

const int N = 1e7 + 5;
bool vis[N + 1];
int p[N + 1], cnt;
void x_x()
{
	f(i, 2, N)
	{
		if (!vis[i])p[++cnt] = i;
		for (int j = 1;p[j] <= N / i;j++)
		{
			vis[p[j] * i] = true;
			if (i%p[j] == 0)break;
		}
	}
}
int fg[N + 1];//-1:偶数个素因子减去,1奇数个素因子加上
void dfs(int cot, ll w, int idx)
{
	(cot & 1) ? fg[w] = 1 : fg[w] = -1;
	f(i, idx + 1, cnt)
	{
		ll now = w * p[i];
		if (now> N)break;
		dfs(cot + 1, now,i);
	}
}
int main()
{
	//freopen("in.txt", "r", stdin);
	x_x();
	dfs(0, (ll)1, 0);
	//debug(cnt);6e5
	int t;
	cin >> t;
	while (t--)
	{
		ll n;cin >> n;
		ll top = sqrt(n + 0.5);
		ll ans = 0;
		f(i, 2, top)
		{
			if(fg[i])ans = ans + (ll)fg[i] * n / ((ll)i*i);
		}
		printf("%lld\n", n-ans);
	}
	return 0;
}

你可能感兴趣的:(基础数论)