• 天守阁的地板 题解


    这题还是挺值得一做的。


    简要题意:
    (1000)

    [prod_{i=1}^n prod_{j=1}^n frac{lcm(i,j)^2}{i*j} ]

    (i、j) 规模均为 (1e6)


    淦。

    [prod_{i=1}^n prod_{j=1}^n frac{lcm(i,j)^2}{i*j} ]

    [= prod_{i=1}^n prod_{j=1}^n frac{i*j}{gcd(i,j)^2} ]

    由于是累乘, 所以拆开来算

    [= frac{ prod_{i=1}^n prod_{j=1}^n i*j } { prod_{i=1}^n prod_{j=1}^n gcd(i,j)^2} ]

    上面的直接预处理, 重点是下面的。

    [prod_{i=1}^n prod_{j=1}^n gcd(i,j)^2 ]

    [= prod_{g=1}^n g^{2 * sum_{i=1}^{lfloor frac{n}g floor} sum_{j=1}^{lfloor frac{n}g floor} [gcd(i,j)==1]} ]

    (f(n) = sum_{i=1}^{n} sum_{j=1}^{n} [gcd(i,j)==1])

    于是

    [prod_{g=1}^n g^{2 * sum_{i=1}^{lfloor frac{n}g floor} sum_{j=1}^{lfloor frac{n}g floor} [gcd(i,j)==1]} ]

    [= prod_{g=1}^n g^{2 * f(lfloor frac{n}g floor)} ]

    可以分块套快速幂算。

    (f(n))怎么算?

    [f(n) = sum_{i=1}^{n} sum_{j=1}^{n} [gcd(i,j)==1] ]

    [= 2*sum_{i=1}^n varphi(i)-1 ]

    也可以预处理。

    总复杂度就是 (O(n)) 预处理 加上 (O( T sqrt n * 快速幂的log))


    Luogu 数据 AC 代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define li long long
    const int mod = 19260817; // prime
    const int maxn = 1e6 + 15;
    li ksm(li a, li b, li p) {
    	li res = 1ll;
    	for(;b;b>>=1, a=(a*a)%p)
    		if(b&1) res = (res*a)%p;
    	return res%p;
    }
    
    li jc[maxn], phi[maxn];
    int pr_cnt, prime[maxn], v[maxn];
    void euler(int n) {
    	jc[0] = 1ll;
    	phi[1] = 1ll;
    	for(int i=2; i<=n; ++i) {
    		if(!v[i]) {
    			v[prime[++pr_cnt] = i] = i;
    			phi[i] = i-1ll;
    		}
    		for(int j=1; j<=pr_cnt; ++j) {
    			if(prime[j] > n/i || prime[j] > v[i]) break;
    			v[prime[j] * i] = prime[j];
    			phi[prime[j] * i] = phi[i] * (i%prime[j] ? prime[j]-1 : prime[j]);
    		}
    	}
    	for(int i=1; i<=n; ++i) {
    		jc[i] = 1ll * jc[i-1] * i % mod;
    		phi[i] += phi[i-1];
    	}
    }
    
    li f(int n) {
    	return 2ll*phi[n] - 1ll;
    }
    
    signed main()
    {
    	euler(1000000);
    	int T,n; cin >> T; while(T--) {
    		scanf("%d", &n);
    		li ans = ksm(jc[n],2*n,mod);
    		li downans = 1ll;
    		for(int i=1,j;i<=n;i=j+1) {
    			j = min(n, n/(n/i));
    			li b = 2 * f(n/i);
    			li a = jc[j] * ksm(jc[i-1],mod-2,mod) % mod;
    			downans *= ksm(a,b,mod);
    			downans = (downans%mod+mod)%mod;
    		}
    		ans *= ksm(downans,mod-2,mod);
    		ans = (ans%mod+mod)%mod;
    		cout << ans << '
    ';
    	}
    	return 0;
    }
    
  • 相关阅读:
    hdoj5327【前缀和思想】
    codeforces 611C
    codeforces 632C
    poj1163 【记忆化搜索·水】
    2016 Multi-University Training Contest 2 A Acperience
    细剖最短路【闲谈,权当是饭后杂文】
    poj1724【最短路】
    [YY题]HDOJ5288 OO’s Sequence
    Codeforces Round #363 (Div. 2) C. Vacations
    POJ2105【进制转化】
  • 原文地址:https://www.cnblogs.com/tztqwq/p/12765467.html
Copyright © 2020-2023  润新知