HDU6434 Count【欧拉函数 线性筛】

HDU6434 I. Count

T次询问,每次询问\(\sum_{i=1}^{n}\sum_{j=1}^{n-1}[gcd(i-j,i+j)=1]\)

\(T\le 1e5, n \le 2e7\)

 对原式进行转换,枚举\(i-j\)\(i-j\)\(j\) ,那么可以变换为\(\sum_{i=1}^{n}\sum_{j=1}^{i-1}[gcd(j,2i-j)=1]\) 

 \(\Rightarrow \sum_{i=1}^{n}\sum_{j=1}^{i-1}[gcd(j,2i)=1]\) 

也就是计算\([1,i-1]\)中与\(2i\)互质的数的个数,也即和\(i\)互质的奇数的个数 = $\frac{\phi(2i)}{2} $ 

所以答案就是: \(\sum_{i=1}^{n}\frac{\phi(2i)}{2} 线性筛预处理之后可以O(1)得到答案\) 

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 2e7+7;
using LL = int_fast64_t;
int phi[MAXN];
LL sum[MAXN];
void calphi(){
    for(int i = 1; i < MAXN; i++) phi[i] = i;
    vector<int> prime;
    for(int i = 2; i < MAXN; i++){
        if(phi[i]==i){
            prime.emplace_back(i);
            phi[i] = i - 1;
        }
        for(int j = 0; j < (int)prime.size(); j++){
            if(i*prime[j]>=MAXN) break;
            phi[prime[j]*i] = phi[prime[j]] * phi[i];
            if(i%prime[j]==0){
                phi[i*prime[j]] = phi[i] * prime[j];
                break;
            }
        }
    }
    for(int i = 1; i < MAXN; i++){
        if(i&1) sum[i] = sum[i-1] + phi[i] / 2;
        else sum[i] = sum[i-1] + phi[i];
    }
}
int main(){
    calphi();
    ____();
    int T;
    for(cin >> T; T; T--){
        int n; cin >> n;
        cout << sum[n] << endl;
    }
    return 0;
}
posted @ 2020-03-25 22:26  _kiko  阅读(...)  评论(...编辑  收藏