zoukankan      html  css  js  c++  java
  • 51nod 1742 开心的小Q (莫比乌斯函数)

    题解:

      分析:- - 完全是看着题解还想半天才会做的。。纠正一个错误,题解中的F(n)和S(n)中都应该是取整而不是下取整.首先S(n)的式子不难想到,问题就在于数据范围太大,强求会T掉.换一下求和顺序,枚举i/d,再枚举d,就可以将原式变形成一个对F(n)求和的式子,然后从1到n中,F(i)有重复,只需要计算一次再乘个数就行了,相当于做一个分块.然后求F(n)时又做了一个变换,可以这么理解:总共有n个数,减去无平方因子数即可,枚举i从1到n,减去每个数的平方倍数的个数,因为这些数一定有平方因子,再由容斥原理,加回被减两次的,以此类推...实际上i超过根号n时没有倍数小于n,所以i只需要到根号n.

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 typedef long long ll;
     6 const int maxn=1e9+5,maxlen=32000;
     7 int mu[maxlen],prinum[maxlen],len=0,a,b,f[maxlen];
     8 void CalPri(){
     9     int num[maxlen];
    10     for(int i=2;i<maxlen;i++)num[i]=i;
    11     for(int i=2;i<maxlen;i++){
    12         if(num[i]==0)continue;
    13         prinum[len++]=i;
    14         mu[i]=-1;
    15         for(int j=2*i;j<maxlen;j+=i)
    16             num[j]=0;
    17     }
    18 }
    19 //预处理前根号n个mu
    20 void Calmu(){
    21     CalPri();
    22     mu[1]=1;
    23     for(int i=2;2*i<=maxlen;i++){
    24         for(int j=0;j<len&&prinum[j]*i<maxlen;j++){
    25             if(i%prinum[j]==0){
    26                 mu[prinum[j]*i]=0;
    27                 break;
    28             }
    29             mu[prinum[j]*i]=-mu[i];
    30         }
    31     }
    32 }
    33 ll F(int n){
    34     if(n==0)return 0;
    35     ll ans=n;
    36     for(int i=1;i*i<=n;i++){
    37         ans-=mu[i]*(n/(i*i));
    38     }
    39     return ans;
    40 }
    41 ll S(int n){
    42     ll ans=0,r,cnt=1;
    43     for(int i=1;i<n&&cnt;i+=cnt){
    44         r=n/i;
    45         cnt=n/r-n/(r+1);
    46         ans+=cnt*F(r);
    47     }
    48     return ans;
    49 }
    50 //ll text(int n){
    51 //    ll ans=0;
    52 //    for(int i=1;i<n;i++){
    53 //        int r=n/i;
    54 //        ans+=F(r);
    55 //    }
    56 //    return ans;
    57 //}
    58 int main(){
    59     Calmu();
    60 //    int n;
    61 //    cin>>n;
    62 //    cout<<S(n)<<' '<<text(n)<<endl;
    63 //        cout<<i<<' '<<F(i)<<endl;
    64     cin>>a>>b;
    65     cout<<S(b)-S(a-1)<<endl;
    66     return 0;
    67 }
  • 相关阅读:
    no-useless-call (Rules) – Eslint 中文开发手册
    Java 8 Stream
    CSS3 ,checked 选择器
    MySQL 数据类型
    _Alignas (C keywords) – C 中文开发手册
    C 库函数 – modf()
    JavaScript E 属性
    SyntaxError.prototype (Errors) – JavaScript 中文开发手册
    swagger和openAPI: 上传文件
    Java中HashMap的putAll()方法: HashMap.putAll()
  • 原文地址:https://www.cnblogs.com/7391-KID/p/6912414.html
Copyright © 2011-2022 走看看