• 天守阁的地板 题解


    这题还是挺值得一做的。


    简要题意:
    (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;
    }
    
  • 相关阅读:
    iOSraywenderlich翻译使用MapKit叠加图层
    IOSTableView学习V2.0
    html的<input>标签常用属性
    SQLSqlServer中decimal(numeric )、float 和 real 数据类型的区别[转]
    PhoneGapV1.0
    IOSPlistV1.0
    IOS使用 UITableView 创建表格应用演练(1)——一个简单的表格应用V3.0
    IOSTableView学习V4.0
    IOS从plist文件加载并显示数据
    学习思路
  • 原文地址:https://www.cnblogs.com/tztqwq/p/12765467.html
Copyright © 2020-2023  润新知