• 51nod 1188


    渊哥给我这题,我还以为是反演,然后还真推出来了

    $$ans=sum_{d=1}(lfloorfrac{n}{i} floor)^2sum_{i|d}mu(frac{d}{i})i$$

    然后51nod 跑了3sec T了

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    inline int read()
    {
        char q=getchar();int ans=0;
        while(q<'0'||q>'9')q=getchar();
        while(q>='0'&&q<='9'){ans=ans*10+q-'0';q=getchar();}
        return ans;
    }
    const int N=5000006;
    
    int prime[N],cnt;
    bool he[N];
    ll ji[N];
    
    void chu()
    {
        ji[1]=1;
        for(int i=2;i<N;++i)
        {
            if(!he[i])
            {
                prime[++cnt]=i;
                ji[i]=i-1;
            }
            for(int j=1;j<=cnt&&prime[j]*i<N;++j)
            {
                he[i*prime[j]]=1;
                if(i%prime[j]==0)
                {
                    ji[i*prime[j]]=ji[i]*prime[j];
                    break;
                }
                ji[i*prime[j]]=ji[i]*ji[prime[j]];
            }
        }
        
        for(int i=1;i<N;++i)
          ji[i]+=ji[i-1];
    }
    
    int T,n;
    
    int main(){
        
        //freopen("in.in","r",stdin);
        
        chu();
    
        T=read();
        
        ll ans;
        int nx;
        
        while(T--)
        {
            n=read();
            
            ans=0;
            for(int i=1;i<=n;i=nx+1)
            {
                nx=n/(n/i);
                ans+=(ll)(n/i)*(n/i-1)*(ji[nx]-ji[i-1]);
            }
            printf("%lld
    ",ans/2);
        }
    
    }
    反演

    正解是

    要求 gcd(n,i)==K 的数量,可以转化成求 gcd(n/K,i/K)==1 的个数

    $$ans=sum_{i=2}^nsum_{j=1}^{i-1}gcd(i,j)$$

    $$ans=sum_{i=2}^nsum_{j|i}^{i-1}phi(frac{i}{j})j$$

    $$ans=sum_{i=2}^nsum_{j=1}^{i*j<=n}phi(i)j$$

    $O(nlog(n))$

    正解也会T,51nod真玄学

    #pragma GCC optimize("O3")
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    inline int read()
    {
        char q=getchar();int ans=0;
        while(q<'0'||q>'9')q=getchar();
        while(q>='0'&&q<='9'){ans=ans*10+q-'0';q=getchar();}
        return ans;
    }
    const int N=5000006;
    const int TT=50006;
    
    int prime[348600],cnt;
    bool he[N];
    int ou[N];
    ll an[N];
    
    void chu()
    {
        ou[1]=1;
        for(int i=2;i<N;++i)
        {
            if(!he[i])
            {
                prime[++cnt]=i;
                ou[i]=i-1;
            }
            for(int j=1;j<=cnt&&prime[j]*i<N;++j)
            {
                he[i*prime[j]]=1;
                if(i%prime[j]==0)
                {
                    ou[i*prime[j]]=ou[i]*prime[j];
                    break;
                }
                ou[i*prime[j]]=ou[i]*ou[prime[j]];
            }
        }
        
        ll t1;
        for(int i=2;i<N;++i)
          for(int j=1;j*i<N;++j)
            an[i*j]+=ou[i]*j;
        for(int i=2;i<N;++i)
          an[i]+=an[i-1];
    }
    
    int T,n;
    
    int main(){
        
        //freopen("in.in","r",stdin);
        //freopen("51nod_Problem_1188_Test_21_In.txt","r",stdin);
        //freopen("out.out","w",stdout);
        
        chu();
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            printf("%lld
    ",an[n]);
        }
    }
    正解
  • 相关阅读:
    文件输入使System.out.println("程序执行完毕!");这句话的内容输入到文件中
    TI CC2541.h的头文件 for IAR
    状态添加Android游戏开发十日通(4)行走,跳跃,碰撞检测
    命令分析分析企业内连接Exchange 移动设备!
    寄存器数据问题反馈集锦W5200/W5300相关
    发票选择SAP 校验发票时:科目5101140100已设置为与税务不相关
    重写方法Android中的HttpsURLConnection连接
    生成数组C面试题精选
    函数路径Croc Champ 2013 Round 2 题解java教程
    排名中国重读“发展Linux,中日两国之比较”有感java教程
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7678678.html
Copyright © 2020-2023  润新知