• [FJWC2020] lg


    首先对(operatorname{lcm})按各个质因子的贡献处理。

    设当前质因子为(p^q),需要计算出(operatorname{lcm})(p^q)(gcd)和。

    这里计算(operatorname{lcm})恰好含有(p^q)的不方便,可以设(operatorname{lcm})(p)的指数小于(q)的进行求和,然后转化成(x_i)不能是(p^q)的倍数。

    然后设(gcd)(p)质因子含有(p^a),则剩余部分(gcd)不能出现(p)的倍数,也不能有数达到(p^{q-a})

    按照套路,可以枚举所有数都是是(T)的倍数的组数(S)(gcd)和就是(sum S cdot varphi(T)),因为(varphi * mathbf{I} = mathbf{id}),每个(gcd)都会在它的约数处被统计一次,也可以用 Mobius 反演证。

    最后就是要设法统计出不是(p)的倍数的数的个数。显然(T mid p),把不合法的减掉就好。还要满足不能每个数都是(p)的倍数,因此要减掉约掉(T)(gcd)仍含(p)的倍数的,于是式子:(设(N = lfloor dfrac{m}{p^a} floor)),以下都是整除:

    [sum_{T=1}^NBig(({N over T} - {N over Tp^{q-a}})^n - ({N over Tp} - {N over Tp^{q-a}})^nBig) varphi(T) ]

    最后统计答案即可。

    这里全部使用整除分块实现,复杂度(mathcal O(n log log n + Nsqrt N)),其中(sqrt N)上不带任何(log)可以用等比数列求和分析出。

    Code

    #include <cstdio>
    #include <algorithm>
    #include <cassert>
    using namespace std;
    #define File(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout)
    typedef long long ll;
    
    const int M = 200005, mod = 998244353, mod1 = 998244352;
    int pown[M];
    template<int mod>
    inline int power(int x, int y){
    	int res = 1;
    	for(; y; y>>=1, x = (1LL * x * x) % mod) if(y & 1) res = (1LL * res * x) % mod;
    	return res;
    }
    
    bool np[M];
    int pr[M], phi[M], pc = 0;
    int phiMp[M];
    void primeList(int n){
    	phi[1] = 1;
    	for(int i=2; i<=n; i++){
    		if(!np[i]) pr[++pc] = i, phi[i] = i - 1;
    		for(int j=1; j<=pc && i * pr[j] <= n; j++){
    			np[i * pr[j]] = true;
    			if(i % pr[j] == 0){
    				phi[i * pr[j]] = phi[i] * pr[j];
    				break;
    			}
    			phi[i * pr[j]] = phi[i] * (pr[j] - 1);
    		}
    	}
    	for(int i=2; i<=n; i++) phi[i] = (phi[i] + phi[i-1]) % mod1;
    }
    
    int main(){
    	int n, m;
    	scanf("%d%d", &n, &m);
    	for(int i=1; i<=m; i++) pown[i] = power<mod1>(i, n);
    	primeList(m);
    	int res = 1;
    	int compGCD = 0;
    	for(int l=1, r; l<=m; l=r+1){
    		r = m / (m / l);
    		compGCD = (compGCD + 1LL * pown[m / l] * (mod1 + phi[r] - phi[l - 1]) % mod1) % mod1;
    	}
    	for(int i=1; i<=pc; i++){
    		int p = pr[i];
    		for(int j=1; j<=m/p; j++)
    			phiMp[j] = (0LL + phiMp[j-1] + (phi[j * p] - phi[j * p - 1] + mod1) % mod1) % mod1;
    		ll pq = p;
    		int nows, lasts = 0;
    		int sum = 0;
    		int q;
    		for(q=1; pq<=m; ++q, pq *= p){ // LCM : p^(q-1)	
    			ll pa = 1;
    			nows = 0;
    			for(int a=0; a<q; a++, pa *= p){ // GCD : p^a
    				int N = m / pa;
    				int last = pq / pa;
    				int now = 0;
    				for(int l=1, r; l<=N; l=r+1){ // Last part GCD
    					r = N / (N / l);
    					int val1 = (N / l) - (N / l / last), val2 = (N / l / p) - (N / l / last);
    					now = (now + 1LL * pown[val1] * ((mod1 + phi[r] - phi[l-1]) % mod1)) % mod1;
    					now = (now + mod1 - 1LL * pown[val2] * ((mod1 + phi[r] - phi[l-1]) % mod1)) % mod1;
    					now = (now + mod1 - 1LL * pown[val1] * ((mod1 + phiMp[r / p] - phiMp[(l - 1) / p]) % mod1) % mod1) % mod1;
    					now = (now + 1LL * pown[val2] * ((mod1 + phiMp[r / p] - phiMp[(l - 1) / p]) % mod1) % mod1) % mod1;
    				}
    				nows = (nows + now * pa) % mod1;
    			}
    			sum = (sum + 1LL * (nows - lasts + mod1) % mod1 * (q - 1)) % mod1;
    			lasts = nows;
    		}
    		sum = (sum + 1LL * (mod1 + compGCD - lasts) % mod1 * (q-1) % mod1) % mod1;
    		res = (1LL * res * power<mod>(p, sum)) % mod;
    	}
    	printf("%d
    ", res);
    	return 0;
    }
    
  • 相关阅读:
    利用ItextPdf、core-renderer-R8 来生成PDF
    把war包放到Tomcat安装文件夹下,不能直接訪问的解决方式
    我的RTOS 之六 -- Touch移植(s5pv210+threadx+ucgui+touch)
    数据库可用率监控工具
    9款极具创意的HTML5/CSS3进度条动画(免积分下载)
    ODBC与JDBC比較
    ORA-02287: 此处不同意序号
    mongodb创建、更新、删除
    jcenter那些事儿
    C#里的应用程序域AppDomain
  • 原文地址:https://www.cnblogs.com/RiverHamster/p/sol-oj4052.html
Copyright © 2020-2023  润新知