zoukankan      html  css  js  c++  java
  • Sum of the Line(ICPC2017 Urumqi)

    题目描述

    Consider a triangle of integers, denoted by T. The value at (r, c) is denoted by Tr,c , where 1 ≤ r and 1 ≤ c ≤ r. If the greatest common divisor of r and c is exactly 1, Tr,c = c, or 0 otherwise.
    Now, we have another triangle of integers, denoted by S. The value at (r, c) is denoted by S r,c , where 1 ≤ r and 1 ≤ c ≤ r. S r,c is defined as the summation    
    Here comes your turn. For given positive integer k, you need to calculate the summation of elements in k-th row of the triangle S.

    输入

    The first line of input contains an integer t (1 ≤ t ≤ 10000) which is the number of test cases.
    Each test case includes a single line with an integer k described as above satisfying 2 ≤ k ≤ 10^8 .

    输出

    For each case, calculate the summation of elements in the k-th row of S, and output the remainder when it divided
    by 998244353.

    样例输入

    2
    2
    3

    样例输出

    1
    5


    题意:对于gcd(i,k) == 1,则S(i,k) = i,否则为0,求S = sigma(S(i,k)^2)

    题解:
    如果没有gcd(i,k)这个限制,则答案就为signa(i^2) 即sigma(i^2) = n*(n+1)*(2*n+1)/6
    gcd(i,k) != 1,说明i 与 k 存在共同的因子(除1外),对于n(<=1e8)的最多的素因子不超过10个,对因子进行容斥
    可以表示为:|U| - |A∪B∪C∪....∪Z| ,A ,B ,...., Z 分别表示为能被某个素数整除的

    首先将k中素因子筛选出来,用唯一分解定理,然后对这些因子进行容斥,可以dfs,也可以用二进制 (0,1表示取或不取,但必须保证至少取一次)

    AC code:
    #include <iostream>
    #include <cstdio>
    using namespace std;
    const int MAXN = 10000000;
    const int mod = 998244353;
    typedef long long ll;
    
    ll fast_pow(ll a,ll n)
    {
        ll ans = 1;
        while(n)
        {
            if(n&1) ans = (ans * a)%mod;
            a = (a * a)%mod;
            n >>= 1;
        }
        return ans;
    }
    const ll six = fast_pow(6,mod-2);
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int tot = 0;
            ll n,k;
            scanf("%lld",&k);
            n = k;
            int prime[100];
            for(int i = 2;i * i <= n;i++)
            {
                if(n % i == 0)
                {
                    prime[tot++] = i;
                    while(n % i == 0)   n /= i;
                }
            }
            if(n != 1) prime[tot++] = n;
            ll ans = k*(k+1)%mod*(2*k+1)%mod*six%mod;
            for(int i = 1;i < (1<<tot);i++)
            {
                n = i;
                int pos = tot - 1,cnt = 0;
                ll ant = 1;
                while(n)
                {
                    if(n&1) ant *= prime[pos],cnt++;
                    pos--;
                    n >>= 1;
                }
                ll m = k/ant;
                if(cnt&1)
                    ans = (ans - ant*ant%mod*m%mod*(m + 1)%mod*(2*m + 1)%mod*six%mod + mod)%mod;
                else
                    ans = (ans + ant*ant%mod*m%mod*(m + 1)%mod*(2*m + 1)%mod*six%mod)%mod;
            }
            printf("%lld
    ",ans);
        }
    }





  • 相关阅读:
    Linux的常用用法
    docker入门实践01
    airflow安装rest api插件发现airflow webserver服务不能启动的解决办法
    27.Spark中transformation的介绍
    1.Cloudera Manager安装
    win10系统不能ping通vmware虚假机解决办法
    在airflow的BashOperator中执行docker容器中的脚本容易忽略的问题
    AirFlow后台运行调度程序
    Airflow怎么删除系统自带的DAG任务
    airflow删除dag不在页面显示
  • 原文地址:https://www.cnblogs.com/lemon-jade/p/9515875.html
Copyright © 2011-2022 走看看