这道题目就是问你第
k
个不是完全平方数正整数倍的数。
好像挺显然的,直接乱搞就好。我们考虑下二分,将问题转化为求函数
F(i)=∑x=1n[i2|x]=[ni]
利用反演
f′(i)=∑i|dμ(di)F(d)
每次暴力枚举因子计算就好了,不过这题需要注意的是容斥的时候要反过来……
时间复杂度 O(Tk√logk) 。代码:
# include <cstdio>
using namespace std;
typedef long long ll;
const ll INF = 1644934081;
const int maxn = 50010;
const int maxs = 50000;
int pri[maxn],tot=0;
bool mark[maxn];
int mu[maxn]={0,-1};
void getmu()
{
mu[1]=1;
for(int i=2;i<=maxs;i++)
{
if(!mark[i])pri[++tot]=i,mu[i]=-1;
for(int j=1;j<=tot&&pri[j]*i<=maxs;j++)
{
mark[i*pri[j]]=1;
if(i%pri[j]==0){mu[i*pri[j]]=0;break;}
else mu[i*pri[j]]=-mu[i];
}
}
}
ll get_sum(ll x){
ll ans = 0;
for (ll i=1;i*i<=x;++i){
ans = ans + x/(i*i)*mu[i];
// printf("%lld ",x/(i*i)*mu[i]);
}
// printf("%lld ",ans);
return ans;
}
ll x;
ll l,r,mid;
ll ans;
int main(){
getmu();
int T; scanf("%d",&T);
while (T--){
scanf("%lld",&x);
// printf("%lld\n",x);
l = x; r = INF;
while (l <= r){
// printf("%lld %lld\n",l,r);
mid = (l+r)>>1;
if (get_sum(mid) >= x){ ans=mid; r=mid-1; }
else l=mid+1;
}
printf("%lld\n",ans);
}
return 0;
}