Min25

我好像只过了模板题
感觉很迷

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 4e5 + 10;
const int mod = 1e9 + 7;
const int iv2 = 500000004;
const int iv6 = 166666668;

int p[N], vis[N], tot = 0;
int sp1[N], sp2[N], sq, m = 0;
ll n, w[N];
int id1[N], id2[N], g1[N], g2[N];


int add(int x){return x >= mod ? x - mod : x;}
int sub(int x){return x < 0 ? x + mod : x;}
void Add(int &x, int y){if((x += y) >= mod && (x -= mod));}
void Sub(int &x, int y){if((x -= y) < 0 && (x += mod));}

int id(ll x)
{
  if(x <= sq) return id1[x];
  return id2[n / x];
}

int S(ll n, int k)
{
  if(p[k] >= n) return 0;
  int t = id(n), res = sub(sub(g2[t] - g1[t]) - sub(sp2[k] - sp1[k]));
  for(int i = k + 1; i <= tot && 1ll * p[i] * p[i] <= n; i++)
  {
    int q = p[i];
    for(ll e = q, c = 1; e <= n; e *= q, c++)
    {
      int o = e % mod;
      Add(res, 1ll * o * add(o - 1 + mod) % mod * (S(n / e, i) + (c > 1)) % mod);
      // cout << n <<" "<< k <<" "<< 1ll * o * add(o - 1 + mod) % mod << endl;
    }
  }
  return res;
}

int qpow(int a, int b)
{
  int res = 1;
  for(; b; b >>= 1, a = 1ll * a * a % mod) if(b & 1) res = 1ll * res * a % mod;
  return res;
}

void sieve(int n)
{
  vis[1] = 1;
  for(int i = 2; i <= n; i++)
  {
    if(!vis[i]) p[++tot] = i;
    for(int j = 1; j <= tot && p[j] * i <= n; j++)
    {
      vis[i * p[j]] = 1;
      if(i % p[j] == 0) break;
    }
  }
  for(int i = 1; i <= tot; i++) sp1[i] = add(sp1[i - 1] + p[i]), sp2[i] = add(sp2[i - 1] + 1ll * p[i] * p[i] % mod);
  return;
}


int S1(ll n)
{
  n %= mod;
  return n * (n + 1) % mod * iv2 % mod;
}

int S2(ll n)
{
  n %= mod;
  return n * (n + 1) % mod * (2 * n % mod + 1) % mod * iv6 % mod;
}



int main()
{
  scanf("%lld", &n);
  sq = (int) sqrt(n) + 1;
  sieve(sq);
  for(ll l = 1, r; l <= n; l = r + 1)
  {
    r = n / (n / l);
    w[++m] = r;
    if(r <= sq) id1[w[m]] = m;
    else id2[n / w[m]] = m;
    g1[m] = sub(S1(r) - 1);
    g2[m] = sub(S2(r) - 1);
  }

  for(int i = 1; i <= tot; i++)
  {
    ll sqr = 1ll * p[i] * p[i];
    for(int j = m; j >= 1 && w[j] >= sqr; j--)
    {
      Sub(g1[j], 1ll * p[i] * sub(g1[id(w[j] / p[i])] - sp1[i - 1]) % mod);
      Sub(g2[j], 1ll * p[i] * p[i] % mod * sub(g2[id(w[j] / p[i])]  - sp2[i - 1]) % mod);
    }
  }
  printf("%d
", add(S(n, 0) + 1));
  return 0;
}




原文地址:https://www.cnblogs.com/SegmentTree/p/13945775.html