• LightOJ1236


    Description

    题目大意:就是求(sum_{i=1}^{n}{sum_{j=i}^{n}{[lcm(i, j) == n]}})的结果。

    思路

    网上有篇博客对这题解释得非常好,记录一下。

    看到这个式子,就想到应该和n的因子有关。
    这里有一个结论
    假设

    [n = p_1^{k_1} cdot p_2^{k_1} ... p_n^{k_n} ]

    设a, b都是n的因子,有

    [a = p_1^{x_1} cdot p_2^{x_1} ... p_n^{x_n} ]

    [b = p_1^{y_1} cdot p_2^{y_1} ... p_n^{y_n} ]

    为了形式的统一,当因子不含质因子p时,令它的次数x=0。
    就有

    [lcm(a, b)=p1^{max(x_1, y_1)} cdot p_2^{max(x_2,y_2)}...p_n^{max(x_n, y_n)} ]

    [gcd(a, b)=p1^{min(x_1, y_1)} cdot p_2^{min(x_2,y_2)}...p_n^{min(x_n, y_n)} ]

    所以对于(lcm(a, b) == n), 就要求这里的(max(x_i, y_i) = k_i),即这两个数必须有一个是(k_i),另一个可以取([0, k_i])
    对于每个(p_i),次数有(2k_i + 1)种选择。故一共有(prod_{i=1}^n{2k_i+1})种选择。由于题目要求i<=j,所以最后要除以2,再加上(i=j=n)的一种情况。
    所以(ans=frac{prod_{i=1}^n{2k_i+1}}{2}+1)

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <algorithm>
    #include <map>
    #include <set>
    #include <vector>
    #include <cstring>
    #include <string>
    #include <stack>
    #include <deque>
    #include <cmath>
    #include <iomanip>
    #include <cctype>
    
    #define endl '
    '
    #define IOS std::ios::sync_with_stdio(0);
    #define pb push_back
    #define mp make_pair
    #define seteps(N) fixed << setprecision(N) 
    
    typedef long long ll;
    using namespace std;
    /*-----------------------------------------------------------------*/
    
    #define INF 0x3f3f3f3f
    const int N = 1e7 + 10;
    const double eps = 1e-8;
    vector<int> prime;
    bool isnp[N];
    
    
    int main() {
        IOS;
        //FO;
        for(int i = 2; i < N; i++) {
            if(!isnp[i]) {
                prime.push_back(i);
                for(int j = 2 * i; j < N; j += i) {
                    isnp[j] = 1;
                }
            }
        }
        int t;
        cin >> t;
        int cas = 0;
        while(t--) {
            ll n;
            cin >> n;
            ll ans = 1;
            ll tn = n;
            for(int i = 0; i < prime.size(); i++) {
                if(1ll * prime[i] * prime[i] > n) break;
                if(tn % prime[i] == 0) {
                    int cnt = 0;
                    while(tn % prime[i] == 0) {
                        tn /= prime[i];
                        cnt++;
                    }
                    ans = ans * (2 * cnt + 1);
                }
            } 
            if(tn != 1) {
                ans = ans * 3;
            }
            ans /= 2;
            ans += 1;
            
            
            cout << "Case " << ++cas << ": " << ans << endl;
        }
    }
    
    
  • 相关阅读:
    正则表达式
    js 联系电话验证实现
    curl 解析
    WinRAR打包时不包含文件夹本身,只打包文件夹里的文件和目录
    如何判断事务是否完成,SqlTransaction
    循环枚举的名称或值
    FileStream 和StreamWriter 一起用时
    ToString yyyy-MM-dd ,MM 小写的故事。
    用7z.exe 压缩整个文件夹里的内容
    VS2010安装选项中有个“图标库”
  • 原文地址:https://www.cnblogs.com/limil/p/13160837.html
Copyright © 2020-2023  润新知