Relatively Prime Powers CodeForces - 1036F (莫比乌斯函数容斥)

Relatively Prime Powers

CodeForces - 1036F

Consider some positive integer xx. Its prime factorization will be of form x=2k1⋅3k2⋅5k3⋅…x=2k1⋅3k2⋅5k3⋅…

Let's call xx elegant if the greatest common divisor of the sequence k1,k2,…k1,k2,… is equal to 11. For example, numbers 5=515=51, 12=22⋅312=22⋅3, 72=23⋅3272=23⋅32 are elegant and numbers 8=238=23 (GCD=3GCD=3), 2500=22⋅542500=22⋅54 (GCD=2GCD=2) are not.

Count the number of elegant integers from 22 to nn.

Each testcase contains several values of nn, for each of them you are required to solve the problem separately.

Input

The first line contains a single integer TT (1≤T≤1051≤T≤105) — the number of values of nn in the testcase.

Each of the next TT lines contains a single integer nini (2≤ni≤10182≤ni≤1018).

Output

Print TT lines — the ii-th line should contain the number of elegant numbers from 22to nini.

Example

Input

4427210

Output

21616

Note

Here is the list of non-elegant numbers up to 1010:

  • 4=22,GCD=24=22,GCD=2;
  • 8=23,GCD=38=23,GCD=3;
  • 9=32,GCD=29=32,GCD=2.

The rest have GCD=1GCD=1.

题意:

给你一个大于等于2的整数N

让你求2~N 中有多少个整数x,

唯一分解后质因子的幂次分别是e1,e2,e3, 时 gcd(e1,e2,e3)=1

思路:

正难则反,一共有N-1个数,我们只需要减去那些gcd不为1的即可,

我们可以分别枚举gcd为2,3,4,5.,,,, 等等

根据容斥原理,gcd 为i时,他对答案的贡献即为 mu[i]*(n^(1/i) -1 ) mu是莫比乌斯函数。

至于系数为什么恰好是莫比乌斯函数,可以先学这篇博客感受一下:

https://www.cnblogs.com/qieqiemin/p/11537681.html

那么我们来看n^(1/i) -1 是2~n中,质因子分解幂次都为i的数的个数。

即n开i次方-1,先去的1就是就是一个数开任何次方都>=1,数字1被算进去了,需要减去。

细节见代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
#define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
#define du2(a,b) scanf("%d %d",&(a),&(b))
#define du1(a) scanf("%d",&(a));
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {a %= MOD; if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}

inline void getInt(int *p);
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
long long gen(long long n, long long k)
{
   long long t = powl(n, 1. / k) - 0.5;
   return t + (powl(t + 1, k) - 0.5 <= n);
}
#define N maxn
bool vis[N];
long long prim[N], mu[N], sum[N], cnt;
void get_mu(long long n)
{
   mu[1] = 1;
   for (long long i = 2; i <= n; i++) {
       if (!vis[i]) {mu[i] = -1; prim[++cnt] = i;}
       for (long long j = 1; j <= cnt && i * prim[j] <= n; j++) {
           vis[i * prim[j]] = 1;
           if (i % prim[j] == 0) { break; }
           else { mu[i * prim[j]] = -mu[i]; }
       }
   }
   for (long long i = 1; i <= n; i++) { sum[i] = sum[i - 1] + mu[i]; }
}
int main()
{
   //freopen("D:\\code\\text\\input.txt","r",stdin);
   //freopen("D:\\code\\text\\output.txt","w",stdout);
   int t;
   get_mu(maxn - 1);
   du1(t);
   while (t--) {
       ll n;
       scanf("%lld", &n);
       ll ans = n - 1;
       for (ll i = 2ll; i <= 64ll; ++i) {
           ans += mu[i] * (gen(n, i) - 1ll);
       }
       printf("%lld\n", ans );
   }
   return 0;
}

inline void getInt(int *p)
{
   char ch;
   do {
       ch = getchar();
   } while (ch == ' ' || ch == '\n');
   if (ch == '-') {
       *p = -(getchar() - '0');
       while ((ch = getchar()) >= '0' && ch <= '9') {
           *p = *p * 10 - ch + '0';
       }
   } else {
       *p = ch - '0';
       while ((ch = getchar()) >= '0' && ch <= '9') {
           *p = *p * 10 + ch - '0';
       }
   }
}




posted @ 2019-09-18 16:56  茄子Min  阅读(343)  评论(0编辑  收藏  举报