• LG P6156 简单题


    ( ext{Problem})


    ( ext{Analysis})

    显然 (f=mu^2)
    那么

    [egin{aligned} sum_{i=1}^n sum_{j=1}^n (i+j)^k &= sum_{d=1}^n mu^2(d) d^{k+1} sum_{i=1}^{lfloor frac{n}{d} floor} sum_{j=1}^{lfloor frac{n}{d} floor} (i+j)^k [gcd(i,j)=1] \ &= sum_{d=1}^n mu^2(d) d^{k+1} sum_{g=1}^{lfloor frac{n}{d} floor} mu(g) g^k sum_{i=1}^{lfloor frac{n}{dg} floor} sum_{j=1}^{lfloor frac{n}{dg} floor} (i+j)^k \ end{aligned} ]

    我们考虑预处理

    [f_1 = sum_{i=1}^n mu^2(d) d^{k+1} \ f_2 = sum_{i=1}^n mu(d) d^k \ f_3 = sum_{i=1}^n sum_{j=1}^n (i+j)^k ]

    这样就可以数论分快套数论分快搞定

    那么就考虑如何预处理这三个前缀和
    显然 (g(d)=d^k) 是个积性函数,于是可以线筛处理处所有 (d^k)
    (f_1)(f_2) 一遍就出来了

    现在就看 (f_3)
    我们对 (f_3) 差分

    [egin{aligned} f_3(n)-f_3(n-1) &= sum_{i=1}^n sum_{j=1}^n (i+j)^k - sum_{i=1}^{n-1} sum_{j=1}^{n-1} (i+j)^k \ &= 2 sum_{i=1}^n (n+i)^k - (2n)^{k} end{aligned} ]

    也就是说我们处理出 (sum_{i=1}^{2n} d^k) 就可以处理出这个 (f_3) 的差分数组
    然后再做一遍前缀和就可以得到 (f_3)

    到此本题就结束了
    注意空间!!

    ( ext{Code})

    #include<cstdio>
    #include<iostream>
    #define re register
    using namespace std;
    typedef long long LL;
    
    const int N = 1e7, P = 998244353;
    LL k;
    int totp, n;
    int pr[N], vis[N + 5], mu[N + 5], pk[N + 5], spk[N + 5], f1[N / 2 + 5], f2[N / 2 + 5], f3[N / 2 + 5];
    
    inline int fpow(LL x, LL y)
    {
    	LL res = 1;
    	for(; y; y >>= 1)
    	{
    		if (y & 1) res = res * x % P;
    		x = x * x % P;
    	}
    	return res;
    }
    
    inline void Euler()
    {
    	vis[1] = mu[1] = pk[1] = 1;
    	for(re int i = 2; i <= N; i++)
    	{
    		if (!vis[i]) pr[++totp] = i, mu[i] = -1, pk[i] = fpow(i, k);
    		for(re int j = 1; j <= totp && i * pr[j] <= N; j++)
    		{
    			vis[i * pr[j]] = 1, pk[i * pr[j]] = (LL)pk[i] * pk[pr[j]] % P;
    			if (!(i % pr[j])) break;
    			mu[i * pr[j]] = -mu[i];
    		}
    	}
    	for(re int i = 1; i <= N / 2; i++) 
    		f1[i] = ((LL)f1[i - 1] + (LL)pk[i] * i % P * mu[i] * mu[i]) % P,
    		f2[i] = ((LL)f2[i - 1] + (LL)pk[i] * mu[i] + P) % P;
    	for(re int i = 1; i <= N; i++) spk[i] = (pk[i] + spk[i - 1]) % P;
    	for(re int i = 1; i <= N / 2; i++) f3[i] = ((LL)f3[i - 1] + 2LL * (spk[2 * i] - spk[i] + P) % P - pk[2 * i] % P + P) % P;
    }
    
    inline int query(int n)
    {
    	LL res = 0;
    	for(re int l = 1, r; l <= n; l = r + 1)
    	{
    		r = n / (n / l);
    		res = (res + (LL)(f2[r] - f2[l - 1] + P) % P * f3[n / l] % P) % P;
    	}
    	return res;
    }
    
    int main()
    {
    	scanf("%d%lld", &n, &k);
    	Euler();
    	LL ans = 0;
    	for(re int l = 1, r; l <= n; l = r + 1)
    	{
    		r = n / (n / l);
    		ans = (ans + (LL)(f1[r] - f1[l - 1] + P) % P * query(n / l)) % P;
    	}
    	printf("%lld
    ", ans);
    }
    
  • 相关阅读:
    腾讯Techo开发者大会PPT分享
    构建三维一体立体化监控,看这一篇就够了!
    ACOUG 联合创始人盖国强:万象更新,数据库技术和生态的发展演进
    全局配置项set_global_options 支持的opts
    InitOpts:初始化配置项:
    数据结构第四章树和森林,期末不挂科指南,第7篇
    Netflix:当你按下“播放”的时候发生了什么?
    Netflix:当你按下“播放”的时候发生了什么?
    搭建vsftpd文件服务器并创建虚拟用户
    搭建vsftpd文件服务器并创建虚拟用户
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/15035376.html
Copyright © 2020-2023  润新知