zoukankan      html  css  js  c++  java
  • BZOJ4916: 神犇和蒟蒻【杜教筛】

    Description

    很久很久以前,有一只神犇叫yzy;

    很久很久之后,有一只蒟蒻叫lty;

    Input

    请你读入一个整数N;1<=N<=1E9,A、B模1E9+7;

    Output

    请你输出一个整数A=sum_{i=1}^N{mu (i^2)};

    请你输出一个整数B=sum_{i=1}^N{varphi (i^2)};

    img

    Sample Input

    1

    Sample Output

    1
    1


    思路

    首先发现第一个一定是1.。。。

    然后发现第二个其实可以表示成

    [sum_{i = 1}^nphi(i)*i ]

    然后我们令

    [f(i)=phi(i)*i \ g(i)=i ]

    那么可以得到

    [ans=Sum(n)=sum_{i=1}^nf(i) ]

    又因为

    [sum_{i = 1}^nsum_{d|i}f(d)g(frac{i}{d})=sum_{i=1}^n i^2=frac{n *(n + 1)*(2n+1)}{6} ]

    [sum_{i = 1}^nsum_{d|i}f(d)g(frac{i}{d})=sum_{k = 1}^ng(k)sum_{d = 1}^{lfloorfrac{n}{k} floor}f(d)=sum_{k = 1}^ng(k)Sum(lfloorfrac{n}{k} floor) ]

    所以有

    [Sum(n)=frac{n *(n + 1)*(2n+1)}{6}-sum_{k = 2}^ng(k)Sum(lfloorfrac{n}{k} floor) ]

    然后上杜教筛板子。。


    #include<bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    
    const ll Mod = 1e9 + 7;
    const ll N = 1e7 + 10;
    const ll inv6 = 166666668;
    const ll inv2 = 500000004;
    
    ll prime[N], cnt = 0;
    ll phi[N], sum[N], vis[N];
    
    map<ll, ll> mp;
    
    ll add(ll a, ll b) {
      return (a += b) >= Mod ? a - Mod : a;
    }
    
    ll sub(ll a, ll b) {
      return (a -= b) < 0 ? a + Mod : a;
    }
    
    ll mul(ll a, ll b) {
      return a * b % Mod;
    }
    
    void get_prime() {
      phi[1] = 1;
      for (ll i = 2; i < N; i++) {
        if (!vis[i]) {
          phi[i] = i - 1;
          prime[++cnt] = i;
        }
        for (ll j = 1; j <= cnt && i * prime[j] < N; j++) {
          vis[i * prime[j]] = 1;
          if (i % prime[j] == 0) {
            phi[i * prime[j]] = phi[i] * prime[j];
            break;
          } else {
            phi[i * prime[j]] = phi[i] * (prime[j] - 1);
          }
        }
      }
      for (ll i = 1; i < N; i++)
        sum[i] = add(sum[i - 1], mul(i, phi[i]));
    }
    
    ll solve(ll n) {
      if (n < N) return sum[n];
      if (mp.count(n)) return mp[n];
      ll res = mul(mul(n, n + 1), mul(2 * n + 1, inv6));
      for (ll i = 2; i <= n; i++) {
        ll j = n / (n / i);
        res = sub(res, mul(solve(n / i), mul(inv2, mul(i + j, j - i + 1))));
        i = j;
      }
      return mp[n] = res;
    }
    
    int main() {
      get_prime();
      ll n; cin >> n;
      cout << 1 << "
    " << solve(n);
      return 0;
    }
    
  • 相关阅读:
    博客园电子期刊2012年6月刊发布啦
    如何在博客园发博客时插入优酷视频
    上周热点回顾(7.167.22)
    “Coding changes the world” 博客园2012主题T恤专题上线
    [转]MySql查询缓存机制
    淘宝店铺开发 ShopSDK 1.x 及 TAE_SDK 2.0
    [转]NHibernate之旅系列文章导航
    MySQL 5.1参考手册 :: 7. 优化
    [转]Nant daily build实践
    [转]淘宝sdk——入门实战之footer.php制作
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/10203298.html
Copyright © 2011-2022 走看看