zoukankan      html  css  js  c++  java
  • UVA GCD

    discription

    Given the value of N, you will have to find the value of G. The definition of G is given below:
    Here GCD(i, j) means the greatest common divisor of integer i and integer j.
    For those who have trouble understanding summation notation, the meaning of G is given in the
    following code:
    G=0;
    for(i=1;i<N;i++)
    for(j=i+1;j<=N;j++)
    {
    G+=gcd(i,j);
    }
    /*Here gcd() is a function that finds
    the greatest common divisor of the two
    input numbers*/
    Input
    The input file contains at most 100 lines of inputs. Each line contains an integer N (1 < N < 4000001).
    The meaning of N is given in the problem statement. Input is terminated by a line containing a single
    zero.
    Output
    For each line of input produce one line of output. This line contains the value of G for the corresponding
    N. The value of G will fit in a 64-bit signed integer.
    Sample Input
    10
    100
    200000
    0
    Sample Output
    67
    13015
    143295493160

    貌似是蓝书上有的一道题,当时刘汝佳是用 N log N 的筛法筛的,但是我们如果把积性函数推出来的话,可以

    把那个log也去掉,做到O(N)预处理,O(1)查询。

    大概最后就是推这么个积性函数: f(T)=Σφ(d)*(T/d)  ,其中d|T

    优化了一个log之后艹爆了时限hhh

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #define ll long long
    #define maxn 4000005
    using namespace std;
    int zs[maxn/4],t=0,low[maxn+5];
    ll f[maxn+5],n,T;
    bool v[maxn+5];
    
    inline void init(){
        f[1]=1,low[1]=1;
        for(int i=2;i<=maxn;i++){
            if(!v[i]) zs[++t]=i,f[i]=i*2-1,low[i]=i;
            for(int j=1,u;j<=t&&(u=zs[j]*i)<=maxn;j++){
                v[u]=1;
                if(!(i%zs[j])){
                    low[u]=low[i]*zs[j];
                    if(low[i]==i) f[u]=f[i]*zs[j]+low[i]*(zs[j]-1);
                    else f[u]=f[i/low[i]]*f[low[u]];
                    break;
                }
                
                low[u]=zs[j];
                f[u]=f[i]*(2*zs[j]-1);
            }
        }
        
        for(int i=1;i<=maxn;i++) f[i]+=f[i-1];
    }
    
    int main(){
        init();
        while(scanf("%lld",&n)==1&&n) printf("%lld
    ",f[n]-n*(n+1)/2);    
        return 0;
    }
  • 相关阅读:
    HTML DOM 06 节点关系
    HTML DOM 05 事件(三)
    HTML DOM 05 事件(二)
    HTML DOM 05 事件(一)
    html DOM 04 样式
    html DOM 03 节点的属性
    html DOM 02 获取节点
    html DOM 01 节点概念
    JavaScript 29 计时器
    JavaScript 28 弹出框
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8319863.html
Copyright © 2011-2022 走看看