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 }
  • 相关阅读:
    ES6关于Promise的用法
    JS进阶篇--JS数组reduce()方法详解及高级技巧
    JavaScript常用数组操作方法,包含ES6方法
    揭密 Vue 的双向绑定
    JavaScript(E5,6) 正则学习总结学习,可看可不看!
    利用scons构建project
    cuda核函数再调用核函数,多层并行
    使用微信JSSDK实现图片上传
    android 自己定义水平和圆形progressbar 仅仅定义一些style就能够
    [LeetCode] 035. Search Insert Position (Medium) (C++)
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/6390912.html
Copyright © 2011-2022 走看看