zoukankan      html  css  js  c++  java
  • Luogu 4240:毒瘤之神的考验

    传送门

    Sol

    分开考虑 (varphi(ij))(ij) 的质因子
    那么

    [varphi(ij)=frac{varphi(i)varphi(j)gcd(i,j)}{varphi(gcd(i,j))} ]

    直接莫比乌斯反演
    (g(x,i)=sum_{j=1}^{x}varphi(ij))
    那么

    [ans=sum_{i=1}^{min(n,m)}g(lfloorfrac{n}{i} floor,i)g(lfloorfrac{m}{i} floor,i)sum_{d|i}mu(frac{i}{d})frac{d}{varphi(d)} ]

    后面的卷积可以直接筛
    (Theta(Tn)) 当然不行了

    (f(i)=sum_{d|i}mu(frac{i}{d})frac{d}{varphi(d)})
    (s(i,j,k)) 表示 (sum_{p=1}^{k}g(i,p)g(j,p)f(p))
    考虑到当 (ile sqrt{n}) 的时候 (s(i,j,k)) 中的 (i,j ge sqrt{n})
    (ige sqrt{n}) 的时候 (s(i,j,k)) 中的 (i,j le sqrt{n})
    所以可以预处理到 (s(80,80,k)) 对于小于 (n/80) 的直接暴力

    # include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int mod(998244353);
    const int maxn(1e5);
    const int blk(80);
    
    inline void Inc(int &x, int y) {
    	if ((x += y) >= mod) x -= mod;
    }
    
    int pr[maxn + 100], phi[maxn + 100], inv[maxn + 100], mu[maxn + 100], tot, f[maxn + 100];
    int test, n, m, ans;
    vector <int> g[maxn + 100], s[blk + 1][blk + 1];
    bitset <maxn + 100> ispr;
      
    int main() {
    	register int i, j, k, len;
    	mu[1] = phi[1] = inv[1] = 1, ispr[1] = 1;
    	for (i = 2; i <= maxn; ++i) inv[i] = (ll)(mod - mod / i) * inv[mod % i] % mod;
    	for (i = 2; i <= maxn; ++i) {
    		if (!ispr[i]) pr[++tot] = i, mu[i] = -1, phi[i] = i - 1;
    		for (j = 1; j <= tot && i * pr[j] <= maxn; ++j) {
    			ispr[i * pr[j]] = 1;
    			if (i % pr[j]) mu[i * pr[j]] = -mu[i], phi[i * pr[j]] = phi[i] * (pr[j] - 1);
    			else {
    				mu[i * pr[j]] = 0;
    				phi[i * pr[j]] = phi[i] * pr[j];
    				break;
    			}
    		}
    	}
    	for (i = 1; i <= maxn; ++i) Inc(mu[i], mod);
    	for (i = 1; i <= maxn; ++i)
    		for (j = i; j <= maxn; j += i) Inc(f[j], (ll)i * inv[phi[i]] % mod * mu[j / i] % mod);
    	for (i = 1; i <= maxn; ++i) {
    		len = maxn / i, g[i].resize(len + 1);
    		for (j = 1; j <= len; ++j) g[i][j] = (g[i][j - 1] + phi[i * j]) % mod;
    	}
    	for (i = 1; i <= blk; ++i)
    		for (j = i; j <= blk; ++j) {
    			len = maxn / j, s[i][j].resize(len + 1);
    			for (k = 1; k <= len; ++k) s[i][j][k] = (s[i][j][k - 1] + (ll)f[k] * g[k][i] % mod * g[k][j] % mod) % mod;
    		}
    	for (scanf("%d", &test); test; --test) {
    		ans = 0, scanf("%d%d", &n, &m);
    		if (n > m) swap(n, m);
    		len = min(n, m / blk);
    		for (i = 1; i <= len; ++i) Inc(ans, (ll)g[i][n / i] * g[i][m / i] % mod * f[i] % mod);
    		for (i = len + 1; i <= n; i = j + 1) {
    			j = min(n / (n / i), m / (m / i));
    			Inc(ans, (s[n / i][m / i][j] - s[n / i][m / i][i - 1] + mod) % mod);
    		}
    		printf("%d
    ", ans);
    	}
        return 0;
    }
    
  • 相关阅读:
    MySQL核心知识学习之路()
    软件设计之路(5)
    软件设计之路(4)
    软件设计之路(4)
    软件设计之路(3)
    软件设计之路(2)
    软件设计之美-软件设计之路
    js将 “2021-07-06T06:23:57.000+00:00” 转换为年月日时分秒
    git pull/push 拉取/推送指定分支的代码
    git clone 指定分支的代码
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/10168004.html
Copyright © 2011-2022 走看看