bzoj 2440 二分+莫比乌斯函数和容斥原理

13 篇文章 0 订阅
3 篇文章 0 订阅

题意:输出第k小的无平方因子的数

无平方因子数:分解质因子后,所有质因数的次数都为1

第k小,考虑二分答案

我们发现,如果直接去找[1,x]的无平方因子数的个数,我们发现,可能对于多个x,[1,x]内的无平方因子数是一样的,所以我们不能找到确切的答案

既然不能直接求,考虑补集思想,我们只要找出[1,x]内有多少个有平方因子的数,再用x减去即可,并且我们可以找到确切的答案

根据不重不漏原则,我们考虑容斥原理

[1,x]内有平方因子的数=x-有一个质因数的次数为2的数的倍数的数的数量+有两个质因数次数为2的数的倍数的数的数量-...(x可以看做1的倍数的个数)

然后根据莫比乌斯函数的定义,对于每个乘积a,前面的符号刚好是μ(a),而x内有floor(x/a*a) 个 a*a的倍数的数

所以[1,x]内,有 sigma(μ(i)*floor(x/a*a))  ( 1<=i<=sqrt(x) ) 个无平方因子的数

const
   inf= 1644934500;
var
        t,l,mid,x,ans,r :longint;
        vis             :array[0..41010] of boolean;
        pri,miu         :array[0..41010] of longint;
procedure pre_do;
var
        i,j:longint;
        tt:longint;
begin
   miu[1]:=1;
   for i:=2 to trunc(sqrt(inf)) do
   begin
      if not vis[i] then
      begin
         inc(t);
         pri[t]:=i;
         miu[i]:=-1;
      end;
      for j:=1 to t do
        if (i*pri[j]>trunc(sqrt(inf))) then break else
        begin
           vis[i*pri[j]]:=true;
           if (i mod pri[j]<>0) then miu[i*pri[j]]:=-miu[i] else
           begin
              miu[i*pri[j]]:=0;
              break;
           end;
        end;
   end;
end;

function solve(x:longint):longint;
var
        ans:longint;
        i:longint;
begin
   ans:=0;
   for i:=1 to trunc(sqrt(x)) do
      inc(ans,miu[i]*(x div (i*i)));
   exit(ans);
end;

begin
   pre_do;
   read(t);
   while (t>0) do
   begin
      dec(t);
      read(x);
      l:=1;r:=inf;
      while (l<=r) do
      begin
         mid:=(int64(l)+int64(r)) div 2;
         if solve(mid)>=x then
         begin
            ans:=mid;r:=mid-1;
         end else l:=mid+1;
      end;
      writeln(ans);
   end;
end.

——by Eirlys


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值