LOJ 2476 「2018 集训队互测 Day 3」蒜头的奖杯

链接:

link

题解:

定义 f(A)=Aμ f ( A ) = A ∗ μ g(A)i=ijnAj g ( A ) i = ∑ i j ≤ n A j

ijkAiBjCkD(i,j)E(i,k)F(j,k) ∑ i ∑ j ∑ k A i B j C k D ( i , j ) E ( i , k ) F ( j , k )

=kCkijAiBjD(i,j)p|(i,k)f(E)pq|(j,k)f(F)p = ∑ k C k ∑ i ∑ j A i B j D ( i , j ) ∑ p | ( i , k ) f ( E ) p ∑ q | ( j , k ) f ( F ) p

=lcm(p,q)nf(E)pf(F)qg(C)lcm(p,q)ipnjqnAipBjqDgcd(ip,iq) = ∑ l c m ( p , q ) ≤ n f ( E ) p f ( F ) q g ( C ) l c m ( p , q ) ∑ i p ≤ n ∑ j q ≤ n A i p B j q D g c d ( i p , i q )

=dxyn/d,(x,y)=1f(E)xdf(F)ydg(C)xydixn/djyn/dAixdBjydDd×(ix,jy) = ∑ d ∑ x y ≤ n / d , ( x , y ) = 1 f ( E ) x d f ( F ) y d g ( C ) x y d ∑ i x ≤ n / d ∑ j y ≤ n / d A i x d B j y d D d × ( i x , j y )

Pi=f(E)id,Qi=f(F)id,Ri=g(C)id,Si=Aid,Ti=Bid,Wi=Did P i = f ( E ) i d , Q i = f ( F ) i d , R i = g ( C ) i d , S i = A i d , T i = B i d , W i = D i d

答案是 xyn,(x,y)=1PxQyRxyixnjynSixTjyW(ix,jy) ∑ x y ≤ n , ( x , y ) = 1 P x Q y R x y ∑ i x ≤ n ∑ j y ≤ n S i x T j y W ( i x , j y )

考虑枚举 x x ,对于所有 y y ,计算

ixnjynSixTjyW(ix,jy) ∑ i x ≤ n ∑ j y ≤ n S i x T j y W ( i x , j y )

=jynTjyd|jyf(W)dd|ix,ixnSix = ∑ j y ≤ n T j y ∑ d | j y f ( W ) d ∑ d | i x , i x ≤ n S i x

=y|zTzd|zf(W)dd|rSr[x|r] = ∑ y | z T z ∑ d | z f ( W ) d ∑ d | r S r [ x | r ]

单次复杂度 O(nnloglogn) O ( n n log ⁡ log ⁡ n ) ,总复杂度 nd=1(n/d)1.5loglogn=n1.5loglogn ∑ d = 1 n ( n / d ) 1.5 log ⁡ log ⁡ n = n 1.5 log ⁡ log ⁡ n

代码:

#include 

using namespace std;

#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define Debug(...) fprintf(stderr, __VA_ARGS__)

typedef long long LL;
typedef long double LD;
typedef unsigned int uint;
typedef pair <int, int> pii;
typedef unsigned long long uLL;

template <typename T> inline void Read(T &x) {
  char c = getchar();
  bool f = false;
  for (x = 0; !isdigit(c); c = getchar()) {
    if (c == '-') {
      f = true;
    }
  }
  for (; isdigit(c); c = getchar()) {
    x = x * 10 + c - '0';
  }
  if (f) {
    x = -x;
  }
}

template <typename T> inline bool CheckMax(T &a, const T &b) {
  return a < b ? a = b, true : false;
}

template <typename T> inline bool CheckMin(T &a, const T &b) {
  return a > b ? a = b, true : false;
}

const int N = 100005;

uLL ans, a[N], b[N], c[N], d[N], e[N], f[N], p[N], q[N], r[N], s[N], t[N], u[N], v[N], w[N];
int n, tot, pri[N];
bool chk[N];

inline void F(uLL *a, int n) {
  for (int i = 1; i <= n; ++i) {
    for (int j = i + i; j <= n; j += i) {
      a[j] -= a[i];
    }
  }
}

inline void G(uLL *a, int n) {
  for (int i = 1; pri[i] <= n; ++i) {
    for (int j = n / pri[i]; j; --j) {
      a[j] += a[j * pri[i]];
    }
  }
}

inline void H(uLL *a, int n) {
  for (int i = 1; pri[i] <= n; ++i) {
    for (int j = 1; j * pri[i] <= n; ++j) {
      a[j * pri[i]] += a[j];
    }
  }
}

int main() {
#ifdef wxh010910
  freopen("d.in", "r", stdin);
#endif
  Read(n);
  for (int i = 2; i <= n; ++i) {
    if (!chk[i]) {
      pri[++tot] = i;
    }
    for (int j = 1; i * pri[j] <= n; ++j) {
      chk[i * pri[j]] = true;
      if (i % pri[j] == 0) {
        break;
      }
    }
  }
  pri[tot + 1] = n + 1;
  for (int i = 1; i <= n; ++i) {
    Read(a[i]);
  }
  for (int i = 1; i <= n; ++i) {
    Read(b[i]);
  }
  for (int i = 1; i <= n; ++i) {
    Read(c[i]);
  }
  for (int i = 1; i <= n; ++i) {
    Read(d[i]);
  }
  for (int i = 1; i <= n; ++i) {
    Read(e[i]);
  }
  for (int i = 1; i <= n; ++i) {
    Read(f[i]);
  }
  G(c, n), F(e, n), F(f, n);
  for (int i = 1; i <= n; ++i) {
    int m = n / i;
    for (int j = 1; j <= m; ++j) {
      p[j] = e[i * j], q[j] = f[i * j], r[j] = c[i * j], s[j] = a[i * j], t[j] = b[i * j], w[j] = d[i * j];
    }
    F(w, m);
    for (int x = 1; x * x <= m; ++x) {
      for (int j = 1; j <= m; ++j) {
        u[j] = v[j] = 0;
      }
      for (int j = x; j <= m; j += x) {
        u[j] = s[j], v[j] = t[j];
      }
      G(u, m), G(v, m);
      for (int j = 1; j <= m; ++j) {
        u[j] *= w[j], v[j] *= w[j];
      }
      H(u, m), H(v, m);
      for (int j = 1; j <= m; ++j) {
        u[j] *= t[j], v[j] *= s[j];
      }
      for (int y = x; x * y <= m; ++y) {
        if (__gcd(x, y) == 1) {
          uLL g = 0, h = 0;
          for (int j = y; j <= m; j += y) {
            g += u[j], h += v[j];
          }
          ans += p[x] * q[y] * r[x * y] * g;
          if (x != y) {
            ans += p[y] * q[x] * r[x * y] * h;
          }
        }
      }
    }
  }
  printf("%llu\n", ans);
#ifdef wxh010910
  Debug("My Time: %.3lfms\n", (double)clock() / CLOCKS_PER_SEC);
#endif
  return 0;
}

你可能感兴趣的:(LOJ 2476 「2018 集训队互测 Day 3」蒜头的奖杯)