zoukankan      html  css  js  c++  java
  • UVa11424 GCD

    (这个题的预处理还是比较神奇的,我没想出来..)
    显然这个题的特点是,n很小,组数却很大,我们想如何预处理.
    首先理解题目在干吗,让我们求出(sum_{i = 1}^{n -1}sum_{j = i + 1}^{n}GCD(i,j))
    套路的做
    先算出
    (GCD(i,j) == x)的数量
    转而求
    (GCD(i/x,j/x) == 1)
    然后就到了预处理的阶段了
    这个题的核心思想在于我们枚举每个因数对于不同n的贡献
    枚举因子
    (sum_{i=1}^{n}sum_{i+1}^{n}GCD(i,j) == x) 的贡献
    (phi[n/x])
    显然这样时间复杂度还是不过关的.((O(n^2)))我们考虑什么时候因子x会加贡献,当n为x的倍数的时候就又会产生贡献.
    像这样预处理时间复杂度(O(log n))

    for(int i = 1;i < maxN;++ i) {
    		for(int j = i + i;j < maxN;j += i) {
    			f[j] += i * phi[j / i];
    		}
    	}
    

    然而我们求出的f数组是(sum_{1}^{n - 1} GCD(i,n))然后造一个前缀和就好了.
    CODE:

    #include <iostream>
    #include <cstdio>
    const int maxN = 200000 + 7;
    
    int phi[maxN];
    bool vis[maxN];
    int prime[maxN];
    int sum[maxN];
    long long int f[maxN];
    
    void init() {
    	int num = 0;
    	vis[1] = 1;
        phi[1] = 1;
        for(int i = 2;i < maxN;++ i) {
            if( !vis[i] ) {
                prime[++ num] = i;
                phi[i] = i - 1;
            }
            for(int j = 1;j <= num && prime[j] * i < maxN;++ j) {
                vis[i * prime[j]] = true;
                if(i % prime[j] == 0) {
                    phi[i * prime[j]] = phi[i] * prime[j];
                    break;
                }
                phi[i * prime[j]] =  phi[i] *( prime[j] - 1);
            }
        }   
    }
    
    int main() {
    	init();
    	int fuck = 1;
    	for(int i = 1;i < maxN;++ i) {
    		for(int j = i + i;j < maxN;j += i) {
    			f[j] += i * phi[j / i];
    		}
    	}
    	for(int i = 1;i < maxN;++ i) {
    		f[i] += f[i - 1];
    	}
    	while(fuck) {
    		int n;
    		scanf("%d",&n) ;
    		if(!n) break;
    		std::cout << f[n] << '
    ';
    	} 
    	return 0;
    }
    
  • 相关阅读:
    线程池。
    等待唤醒机制。
    第一册:lesson 131.
    线程同步机制。
    第一册: lesson 129。
    线程实现方式。
    第一册:lesson 125.
    第一册:Lesson 123.
    黄渤的谈话。
    K3 KFO 手册
  • 原文地址:https://www.cnblogs.com/tpgzy/p/9549718.html
Copyright © 2011-2022 走看看