K: Sum of the Line
时间限制: 1 Sec 内存限制: 128 MB
提交: 93 解决: 18
[提交] [状态] [讨论版] [命题人:admin]
题目描述
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
题意:
求 T(k,i)定义为 : 若 gcd 为1 则为 i 否则 为 0 '
类似:
T(1,1)
T(2,2) T(2,2)
T(3,3) T(3,3) T(3,3)
T(4,4) T(4,4) T(4,4) T(4,4)
....
T(K,K) T(K,K) T(K,K) T(K,K)
思路: 容斥原理:
可以先求 总的 sum =
然后 减去 容斥的部分 就可以了,
需要把 质因子 以及其倍数所在的那一行 求出;
对每一个质因子 式子为:
提取 p^2 得: 然后 在套用 公式 ,求
转化成 求 k 的质因子, 每一个质因子 就是 容斥的一部分,
然后 需要做的操作是 对与 所有的质因子, 取 任意两个, 任意三个, 任意四个, 到 任意n个 的 倍数, 这是重复的部分, 这里
因为1e8 的质因子最多有9个 , 所以可以采取 暴力 二进制 枚举01 ,判断
容斥时 遵循 : 奇数减 偶数加的 原则。
具体 看代码:
代码:
#include <bits/stdc++.h>
#include <stdio.h>
#define rep(i,a,n) for(int i = a;i<=n;i++)
using namespace std;
const int maxn = 1e8+10;
const int mod = 998244353;
typedef long long ll;
inline ll qpow(ll a,ll n)
{
ll res = 1;
for(;n;n>>=1)
{
if(n&1)
res = res*a %mod;
a = a*a%mod;
}
return res;
}
ll GetSum(ll n)
{
return ( (n*(n+1)%mod*(2*n+1ll)%mod)*qpow(6ll,mod-2)%mod)%mod;
}
ll a[200];
int k ;
void table(ll n)
{
ll temp=n;
if(temp%2==0)
{
a[k++]=2;
while(temp%2==0)
temp/=2;
}
for(int i=3;i<=sqrt(n)+1;i+=2)
{
if(temp%i==0)
{
a[k++]=i;
while(temp%i==0)
temp/=i;
}
}
if(temp!=1)
a[k++]=temp;
}
int main(int argc, char const *argv[])
{
int T;
scanf("%d",&T);
while(T--)
{
ll n;
k = 0;
memset(a,0,sizeof(a));
scanf("%lld",&n);
table(n);
ll sum = GetSum(n);
int binary[100];
ll res = 0;
for(int i = 0;i < k;i++)
{
////////
//cout<<"VVV "<<a[i]<<endl;
////////
ll up = 1ll*n/a[i];
ll tep = qpow(1ll*a[i],2ll)*GetSum(up)%mod;
res = (res + tep )%mod;
}
int bi = 0;
for(int i = 0 ; i < qpow(2ll,k);i++)
{
int te = i;
while(te)
{
binary[bi++] = te%2;
te/=2;
}
int num = 0 ;
ll rsum = 1;
rep(j,0,bi-1)
{
if( binary[j]==1)
{
num++;
rsum *= a[j];
}
}
bi = 0;
if( num < 2 || rsum > n )
continue;
int dc = 1;
if( num%2==0)
{
ll up = 1ll*n/rsum;
res = (res - qpow(1ll*rsum,2ll)*GetSum(up))%mod;
}
else
{
ll up = 1ll*n/rsum;
res = (res + qpow(1ll*rsum,2ll)*GetSum(up))%mod;
}
}
//cout<<sum<< " "<<res<<endl;
printf("%lld\n",(sum-res+mod)%mod );
}
return 0;
}