zoukankan      html  css  js  c++  java
  • UVA 11426 GCD

    题意:求sum(gcd(i,j),1<=i<j<=n)。

    思路:首先能够看出能够递推求出ans[n],由于ans[n-1]+f(n),当中f(n)表示小于n的数与n的gcd之和

    问题转化为了求f(n),由于小于n的数与n的gcd一定是n的因数,

    所以f(n)能够表示为sum(i)*i,当中sum(i)表示全部和n的gcd为i的数的数量,我们要求满足gcd(a, n) = i,的个数,能够转化为求gcd(a/i, n/i) = 1的个数,

    于是能够发现sun(i) = phi(n/i),这里枚举n的因数的方法仿照素数筛法,时间复杂度为O(nlogn).

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<queue>
    #include<stack>
    #include<string>
    #include<map>
    #include<set>
    #include<ctime>
    #define eps 1e-6
    #define LL long long
    #define pii (pair<int, int>)
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    
    const int maxn = 5000000;
    //const int INF = 0x3f3f3f3f;
    int n; 
    LL ans[5000000];
    
    int phi[maxn];
    void phi_table(int n) {
    	for(int i = 2; i <= n; i++) phi[i] = 0;
    	phi[1] = 1;
    	for(int i = 2; i <= n; i++) if(!phi[i])
    		for(int j = i; j <= n; j+=i) {
    			if(!phi[j]) phi[j] = j;
    			phi[j] = phi[j] / i * (i-1);
    		}
    } 
    
    void init() {
    	phi_table(4000000);
    	ans[1] = 0;
    	for(int i = 1; i <= 4000000; i++) {
    		for(int j = i*2; j <= 4000000; j+=i) {
    			ans[j] += phi[j/i]*i; 
    		}
    	}
    	for(int i = 2; i <= 4000000; i++) ans[i] += ans[i-1];
    }
    
    int main() {
        //freopen("input.txt", "r", stdin);
    	init(); //cout << phi[3] << endl;
    	while(scanf("%d", &n) == 1 && n) {
    		cout << ans[n] << endl;
    	}
        return 0;
    }
    
    
    
    
    


  • 相关阅读:
    js入门之DOM
    js入门之字符串常用的方法
    js入门之内置数组对象 Array
    js入门之内置对象Date
    js入门之内置对象Math
    js入门之对象
    js入门之函数
    js入门之数组
    js入门第二篇之流程控制语句
    js入门第一篇
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/7011162.html
Copyright © 2011-2022 走看看