zoukankan      html  css  js  c++  java
  • 1742 开心的小Q

    如果一个数字存在一个约数是完全平方数,那么小Q就认为这个数是有趣的。

    小Q喜欢收集有趣的数字,每找到一个有趣的数,小Q就会变得很开心。
    小Q发现12是有趣的,18也是有趣的,它们都是36的约数,而在36的约数中,还有3个数是有趣的,它们是4、9、36。
    小Q很好奇,在a~b里每个数字各有多少个有趣的约数,由于a和b太大了,所以他只想知道这些个数之和是多少。
    例如4有1个有趣的约数,8有2个有趣的约数,9有1个有趣的约数,所以1~10里每个数的有趣约数个数之和是4。
    Input
    输入数据包括2个数:a, b,中间用空格分隔。(1≤a≤b≤10^9)
    Output
    输出a~b里每个数字的有趣约数个数之和。
    Input示例
    1 10
    Output示例
    4
    思路:分块+莫比乌斯;
    根据莫比乌斯abs(mul[i]) = 0表示i这个数有平方项因子,abs(mul[i]) = 1表示这个数没有平方项因子。
    ,那么答案就是S(m)-S(n-1);
    
    
    然后分块计算,前sqrt(n)直接用公式,然后后面的因为(n/i)在一段区间内是相同的值,那么我们只要算出这个区间的长度,这个容斥下就行了,算出区间内符合是含有平方因子的数。
     1 #include<bits/stdc++.h>
     2 typedef long long LL;
     3 using namespace std;
     4 bool prime[100005];
     5 LL ak[100005];
     6 LL mul[100005];
     7 const int BufferSize=1<<16;
     8 char buffer[BufferSize],*head,*tail;
     9 inline char Getchar() {
    10     if(head==tail) {
    11         int l=fread(buffer,1,BufferSize,stdin);
    12         tail=(head=buffer)+l;
    13     }
    14     return *head++;
    15 }
    16 inline int read() {
    17     int x=0,f=1;char c=Getchar();
    18     for(;!isdigit(c);c=Getchar()) if(c=='-') f=-1;
    19     for(;isdigit(c);c=Getchar()) x=x*10+c-'0';
    20     return x*f;
    21 }
    22 LL slove(LL n);
    23 int akk[100005];
    24 int main(void)
    25 {
    26     int cn = 0;
    27     mul[1] = 1;int ap = 0;
    28     for(int i = 2; i <= 100000; i++)
    29     {
    30         if(!prime[i])
    31         {
    32             ak[cn++] = i;
    33             mul[i] = -1;
    34         }
    35         for(int j = 0; j < cn&&(LL)ak[j]*i<=100000; j++)
    36         {
    37             if(i%ak[j])
    38             {
    39                 prime[i*ak[j]] = true;
    40                 mul[i*ak[j]] = -mul[i];
    41             }
    42             else
    43             {
    44                 prime[i*ak[j]] = true;
    45                 mul[i*ak[j]] = 0;
    46                 break;
    47             }
    48         }
    49         if(mul[i])akk[ap++] = i;
    50     }
    51     LL n,m;
    52    n = read(),m=read();
    53     LL c = sqrt(n); LL sum = 0;
    54     sum = slove(m)-slove(n-1);
    55     printf("%lld
    ",sum);
    56     return 0;
    57 }
    58 LL slove(LL n)
    59 {   if(n == 0)return 0;
    60     LL c = sqrt(n);LL sum = 0;
    61     for(int i = 2;i <= c;i++)
    62     {
    63         if(!mul[i])
    64         {
    65             sum += n/i;
    66         }
    67     }
    68     for(int i = 1;i <= n/c-1;i++)
    69     {
    70         LL a,b;
    71         a = n/(i+1);
    72         b = n/i;
    73         a++;LL v = 0;
    74         for(int j = 0;akk[j] <= sqrt(b);j++)
    75         {
    76             sum -= (mul[akk[j]]*((b)/(akk[j]*akk[j])-(a-1)/(akk[j]*akk[j])))*i;
    77         }
    78     }
    79     return sum;
    80 }
  • 相关阅读:
    解决 搭建Jekins过程中 启动Tomcat的java.net.UnknownHostException异常
    射手和农场主
    java 和 JS(javaScript)中的反斜杠正则转义
    分享修改密码的SharePoint Web part: ITaCS Change Password web part
    分享微软官方Demo用的SharePoint 2010, Exchange 2010, Lync 2010虚拟机
    Office 365 的公共网站的一些限制及解决的办法
    SharePoint 2013 关闭 customErrors
    安装 KB2844286 导致SharePoint 2010 XSLT web part 显示出现错误
    安装Office Web Apps Server 2013 – KB2592525安装失败
    如何将hyper-v虚拟机转换成vmware的虚拟机- 转换SharePoint 2010 Information Worker Demonstration and Evaluation Virtual Machine (SP1)
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/6390912.html
Copyright © 2011-2022 走看看