upc5222: Sum of the Line(容斥)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sxh759151483/article/details/82078088

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.

题意大体可以概括为给一个k求小于k并且与k互质的所有数的平方和。

要求的答案可以用 1~k的平方和(k * (k + 1) * (2 * k + 1) * 6) - 与k不互质的数的平方和。

与k不互质的数的平方和:

先把k的所有素数因子求出来,

与k有一个共同因子的数的平方和。(∑i^2)*m^2   (1 < i < n / m,  i∈Z)(m是因子的积)

-与k有两个共同因子的数的平方和。(∑i^2)*m^2   (1 < i < n / m,  i∈Z)(m是因子的积)

+与k有三个共同因子的数的平方和。(∑i^2)*m^2   (1 < i < n / m,  i∈Z)(m是因子的积)

.....................................................

+(-1)^(n+1)  *  与k有n个共同因子的数的平方和。(∑i^2)*m^2   (1 < i < n / m,  i∈Z)(m是因子的积)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 998244353;
const int maxn = 2e4+5;
inline ll qpow(ll a,ll b){ll r=1,t = a % mod; while(b){if(b&1)r=(r*t)%mod;b>>=1;t=(t*t)%mod;}return r;}
inline ll inv(ll b){return b==1?1:(mod-mod/b)*inv(mod%b)%mod;}
int a[maxn], prime[maxn], p, vis[maxn], cnt;
ll get(ll x) {
    return x * (x + 1) % mod * (2 * x + 1) % mod * inv(6) % mod;
}
void init(){
    cnt = 0;
    memset(vis, 0, sizeof(vis));
    for(int i = 2; i < maxn; i++){
        if(!vis[i]){
            prime[cnt++] = i;
            for(int j = i + i; j < maxn; j += i)
                vis[j] = 1;
        }
    }
}


void decompose(ll x){
    p = 0;
	for(int i = 0; i < cnt; i++){
        if(x < prime[i])
            break;
		if(x % prime[i] == 0){
			a[p++] = prime[i];
			while(x % prime[i] == 0)
				x /= prime[i];
		}
	}
	if(x > 1)
		a[p++] = x;
}

int main() {
    init();
    int T;
    scanf("%d", &T);
    while(T--) {
        ll n;
        scanf("%lld", &n);
        if(n == 0 || n == 1) {
            puts("0");
            continue;
        }
        decompose(n);
        ll sum = get(n);
        for(int i = 1; i < 1 << p; i++) {//所有的因子总共有2^p种组合方式
            ll res = 0, temp = 1;
            for(int j = 0; j < p; j++) {
                if(i & (1 << j)) {
                    temp *= a[j];
                    res++;
                }
            }
            ll t = get(n / temp) * temp % mod * temp % mod;
            if(res & 1)
                sum = (sum - t + mod) % mod;
            else
                sum = (sum + t) % mod;
        }
        printf("%lld\n", sum);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sxh759151483/article/details/82078088
sum