zoukankan      html  css  js  c++  java
  • 51NOD1965:奇怪的式子

    传送门
    拆开变成

    [prod_{i=1}^{n}sigma_0(i)^{mu(i)}prod_{i=1}^{n}sigma_0(i)^{i} ]

    考虑 (prod_{i=1}^{n}sigma_0(i)^{mu(i)})
    运用 (mu) 的性质,设 (c(i)) 表示 (i) 的质数因子个数
    那么就是

    [prod_{i=1}^{n}2^{mu(i)c(i)}=2^{sum_{i=1}^{n}mu(i)c(i)} ]

    只需要设
    (f(x,j)) 表示 (1)(x) 最小质因子大于等于第 (j) 个质数的合数的 (mu(i)c(i)) 的和
    (g(x,j)) 表示 (1)(x) 最小质因子大于等于第 (j) 个质数的合数的 (mu(i)) 的和
    预处理出 (cntp(i)) 表示 (1)(x) 的质数个数就可以递推了
    这一部分直接 (min25) 筛即可
    考虑 (prod_{i=1}^{n}sigma_0(i)^{i})
    分开考虑每个质数的贡献
    (s(n,p,k)) 表示 (1)(n) 中只含有 (p^k) 这个因子不含 (p^i,i e k) 的数的和
    (P) 为质数集合
    那么

    [prod_{i=1}^{n}sigma_0(i)^{i}=prod_{pin P}prod_{k=1}(k+1)^{s(n,p,k)} ]

    (Sum(x)=sum_{i=1}^{x}i)
    那么

    [s(n,p,k)=p^kSum(lfloorfrac{n}{p^k} floor)-p^{k+1}Sum(lfloorfrac{n}{p^{k+1}} floor) ]

    (ple sqrt{n}) 的时候直接暴力计算
    (p > sqrt{n}) 的时候,显然 (k) 最多就是 (1)
    那么

    [s(n,p,k)=pSum(lfloorfrac{n}{p} floor) ]

    (min25) 筛预处理出 (S(x)) 表示 (1)(x) 的质数的和,然后数论分块即可
    注意常数优化QwQ

    # include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const ll mod(1e12 + 39);
    const ll phi(1e12 + 38);
    const int maxn(1e6 + 5);
    
    inline ll Mul1(ll x, ll y) {
        register ll ret = x * y - (ll)((long double)x / mod * y + 0.5) * mod;
        return ret < 0 ? ret + mod : ret;
    }
    
    inline ll Mul2(ll x, ll y) {
        register ll ret = x * y - (ll)((long double)x / phi * y + 0.5) * phi;
        return ret < 0 ? ret + phi : ret;
    }
    
    inline ll Pow(ll x, ll y) {
    	register ll ret = 1;
    	for (; y; y >>= 1, x = Mul1(x, x))
    		if (y & 1) ret = Mul1(ret, x);
    	return ret;
    }
    
    inline void Inc1(ll &x, ll y) {
    	x = x + y >= mod ? x + y - mod : x + y;
    }
    
    inline void Inc2(ll &x, ll y) {
    	x = x + y >= phi ? x + y - phi : x + y;
    }
    
    inline ll Dec1(ll x, ll y) {
    	return x - y < 0 ? x - y + mod : x - y;
    }
    
    inline ll Dec2(ll x, ll y) {
    	return x - y < 0 ? x - y + phi : x - y;
    }
    
    int test, pr[maxn], tot, d, id1[maxn], id2[maxn], cnt;
    ll n, val[maxn], cntp[maxn], f[maxn], g[maxn], s[maxn], sp[maxn];
    bitset <maxn> ispr;
    
    # define ID(x) ((x) <= d ? id1[x] : id2[n / (x)])
    
    inline ll Sum1(ll x) {
    	return (x & 1) ? Mul1(x, (x + 1) / 2) : Mul1(x / 2, x + 1);
    }
    
    inline ll Sum2(ll x) {
    	return (x & 1) ? Mul2(x, (x + 1) / 2) : Mul2(x / 2, x + 1);
    }
    
    inline ll GetSum(ll x, ll v1, ll v2) {
    	return Dec2(Mul2(v1, Sum2(x / v1)), Mul2(v2, Sum2(x / v2)));
    }
    
    inline void Solve() {
    	while (cnt) f[cnt] = g[cnt] = 0, cnt--;
    	register ll i, j, id, ans1, ans2, v, ret, lst, cur;
    	for (d = sqrt(n), i = 1; i <= n; i = j + 1) {
    		j = n / (n / i), val[++cnt] = n / i;
    		val[cnt] <= d ? id1[val[cnt]] = cnt : id2[j] = cnt;
    		cntp[cnt] = val[cnt] - 1, s[cnt] = Sum2(val[cnt]) - 1;
    	}
    	for (i = 1; i <= tot && pr[i] <= n / pr[i]; ++i)
    		for (j = 1; j <= cnt && pr[i] <= val[j] / pr[i]; ++j) {
    			id = ID(val[j] / pr[i]), cntp[j] -= cntp[id] - i + 1;
    			Inc2(s[j], Mul2(pr[i], Dec2(sp[i - 1], s[id])));
    		}
    	for (--i; i; --i)
    		for (j = 1; j <= cnt && pr[i] <= val[j] / pr[i]; ++j) {
    			id = ID(val[j] / pr[i]);
    			v = Dec2(cntp[id] - i, g[id]), Inc2(g[j], v);
    			Inc2(v, cntp[id] - i), Inc2(f[j], Dec2(v, f[id]));
    		}
    	for (i = 1; i <= cnt; ++i) Inc2(f[i], phi - cntp[i]);
    	ans1 = Pow(2, f[ID(n)]), ans2 = 1;
    	for (i = 1; i <= tot && pr[i] <= n / pr[i]; ++i)
    		for (j = 1, v = pr[i]; v <= n; v = v * pr[i], ++j) ans2 = Mul1(ans2, Pow(j + 1, GetSum(n, v, v * pr[i])));
    	for (lst = sp[i - 1], ret = 0, i = pr[i]; i <= n; i = j + 1) {
    		j = n / (n / i);
    		Inc2(ret, Mul2(Dec2(cur = s[ID(j)], lst), Sum2(n / i))), lst = cur;
    	}
    	ans2 = Mul1(ans2, Pow(2, ret)), printf("%lld
    ", Mul1(ans1, ans2));
    }
    
    int main() {
    	register int i, j;
    	ispr[1] = 1;
    	for (i = 1; i < maxn; ++i) {
    		if (!ispr[i]) pr[++tot] = i, sp[tot] = (sp[tot - 1] + i) % phi;
    		for (j = 1; j <= tot && i * pr[j] < maxn; ++j) {
    			ispr[i * pr[j]] = 1;
    			if (!(i % pr[j])) break;
    		}
    	}
    	scanf("%d", &test);
    	while (test) scanf("%lld", &n), Solve(), --test;
        return 0;
    }
    
  • 相关阅读:
    IE 下 telerik RadAjaxManager 多次请求,LoadingPanel 点击消失
    Razor 越来越像 Rails 了
    MongoDB 初学
    Virtual PC 2007 SP1 中,Windows Server 2008 SP2 下安装 SQL Server 2008 R2
    VB 程序员:不要放松对自己的要求
    Linq to SQL bug: Char(1) maps to System.Char
    Linq to SQL: System.InvalidCastException: Specified cast is not valid
    ASP.NET 4: 允许对URL中的特殊字符串放宽要求
    IE 8 打开新 Tab 页报错 window.external.BuildNewTabPage()
    过完年了
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/10177829.html
Copyright © 2011-2022 走看看