zoukankan      html  css  js  c++  java
  • spoj gcdex

    题解:

    首先我们设gcd(i,j)=k

    所以我们就要求对于所有k的方案总数

    可以线性帅选欧拉函数

    然后算法一:枚举k,O(NT)

    算法二:考虑到我们只要n/k的整数部分

    容易证明是sqrt(n)级别的

    所以就可以在O(Tsqrt(n))的时间内解决

    但是要考虑卡常数

    代码:

    #include<bits/stdc++.h>
    typedef long long ll;
    const int N=1000010;
    ll ans,res[N],g[N],s[N];
    int    p[N],f[N],len=0,n,a[N],b[N],tmp;
    int main()
    {
        freopen("1.in","r",stdin);
        freopen("1.out","w",stdout);
        for (int i=2;i<N;i++)
         {
            if (!f[i])f[i]=i,p[++len]=i;
            for (int j=1;j<=len&&p[j]<=f[i]&&p[j]<=N/i;j++)f[i*p[j]]=p[j];        
         }
        for (int i=2;i<N;i++)
         {
            if (f[i]==i) g[i]=i-1;
            else
             {
                int x=i/f[i];
                if (f[i]==f[x]) g[i]=g[x]*f[i];
                else g[i]=g[x]*(f[i]-1);
             }
         }    
        for (int i=1;i<N;i++)
         {
            s[i]=s[i-1]+i;
            g[i]+=g[i-1];
            res[i]=-1;
         }
        while (scanf("%d",&n),n)
         {    
            ans=0;
            int j;
            for (j=1;j*j<=n;j++)
             {
                a[j]=n/j;
                ans+=g[a[j]]*j;
             }
            for (int k=n/j;j<=n;k--)
             {
                ans+=g[k]*(s[a[k]]-s[j-1]);
                j=a[k]+1;
             }
            res[n]=ans;
            printf("%lld
    ",ans);
         }
    }
  • 相关阅读:
    19. Remove Nth Node From End of List
    18. 4Sum
    16. 3Sum Closest
    15. 3Sum
    17. Letter Combinations of a Phone Number
    A Network-based End-to-End Trainable Task-oriented Dialogue System
    14. Longest Common Prefix
    36. Valid Sudoku
    29. Divide Two Integers
    32. Longest Valid Parentheses
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8849291.html
Copyright © 2011-2022 走看看