zoukankan      html  css  js  c++  java
  • [BZOJ2440]完全平方数解题报告|莫比乌斯函数的应用

    完全平方数

      小 X 自幼就很喜欢数。但奇怪的是,他十分讨厌完全平方数。他觉得这些数看起来很令人难受。由此,他也讨厌所有是完全平方数的正整数倍的数。然而这丝毫不影响他对其他数的热爱。 
      这天是小X的生日,小 W 想送一个数给他作为生日礼物。当然他不能送一个小X讨厌的数。他列出了所有小X不讨厌的数,然后选取了第 K个数送给了小X。小X很开心地收下了。 
      然而现在小 W 却记不起送给小X的是哪个数了。你能帮他一下吗?

      还记得第一次接触这道题是一年前吧..那时候参加了一场某OJ的比赛

      然后并不会做..在discuss里面发现是“BZOJ2440原题”

      然后看到了一个叫做莫比乌斯函数的东西...很努力地看但是仍然没看懂...

      也奇怪..现在就能看懂了呢...

      

      莫比乌斯函数:

      μ(1)=1;

      对于每个质因子的次数都为1的数n,假设其能拆分出k个质因子,μ(n)=(-1)^k

      其他情况下μ(n)=0

      构造方法:

      首先容易证明莫比乌斯函数是积性函数

      然后用线筛

    procedure build;
    var m:int64;
        i,j:longint;
    begin
        fillchar(vis,sizeof(vis),true);
        prime[0]:=0;
        m:=trunc(sqrt(INF));mu[1]:=1;
        for i:=2 to m do
        begin
            if vis[i] then
            begin
                inc(prime[0]);
                prime[prime[0]]:=i;
                mu[i]:=-1;
            end;
            for j:=1 to prime[0] do
            begin
                if i*prime[j]>m then break;
                vis[i*prime[j]]:=false;
                if i mod prime[j]=0 then
                begin
                    mu[prime[j]*i]:=0;
                    break;
                end;
                mu[prime[j]*i]:=-mu[i];
            end;
        end;
    end;

      对于这道题,很容易想到二分答案+容斥

      然后发现由偶数个次数为一的质数乘起来的完全平方因子,对答案的贡献是正的,奇数个是负的

      这个就可以用莫比乌斯函数来替代

     1 program bzoj2440;
     2 const INF = 1644934500;maxn = 41000;
     3 var test,L,R,ans,k,mid:int64;
     4     tt:longint;
     5     prime,mu:array[-1..maxn]of int64;
     6     vis:array[-1..maxn]of boolean;
     7 
     8 procedure build;
     9 var m:int64;
    10     i,j:longint;
    11 begin
    12     fillchar(vis,sizeof(vis),true);
    13     prime[0]:=0;
    14     m:=trunc(sqrt(INF));mu[1]:=1;
    15     for i:=2 to m do
    16     begin
    17         if vis[i] then
    18         begin
    19             inc(prime[0]);
    20             prime[prime[0]]:=i;
    21             mu[i]:=-1;
    22         end;
    23         for j:=1 to prime[0] do
    24         begin
    25             if i*prime[j]>m then break;
    26             vis[i*prime[j]]:=false;
    27             if i mod prime[j]=0 then
    28             begin
    29                 mu[prime[j]*i]:=0;
    30                 break;
    31             end;
    32             mu[prime[j]*i]:=-mu[i];
    33         end;
    34     end;
    35 end;
    36 
    37 function solve(x:int64):int64;
    38 var sum:int64;
    39     i:longint;
    40 begin
    41     sum:=0;
    42     for i:=1 to trunc(sqrt(x)) do
    43             inc(sum,(x div (int64(i)*i))*mu[i]);
    44 
    45     exit(sum);
    46 end;
    47 
    48 begin
    49     assign(input,'bzoj2440.in');reset(input);
    50     readln(test);
    51     build;
    52         for tt:=1 to test do
    53     begin
    54         readln(k);
    55         L:=1;R:=INF;ans:=-1;
    56         while L<=R do
    57         begin
    58             mid:=(L+R) >> 1;
    59             if solve(mid)>=k then
    60             begin
    61                 ans:=mid;R:=mid-1;
    62             end else L:=mid+1;
    63         end;
    64         writeln(ans);
    65     end;
    66 end.

      

  • 相关阅读:
    第一次工作 第一星期问题总结。
    IOS 中使用token机制来验证用户的安全性
    地址栏连接参数修改
    JavaScript反调试技巧
    简谈前端存储
    跨域的原因,场景,方法
    vue学习笔记(一)关于事件冒泡和键盘事件 以及与Angular的区别
    vue入门 vue与react和Angular的关系和区别
    详细图解作用域链与闭包
    jQuery的ajax详解
  • 原文地址:https://www.cnblogs.com/mjy0724/p/4480844.html
Copyright © 2011-2022 走看看