BZOJ 3529: [Sdoi2014]数表
二次聯(lián)通門 :?BZOJ 3529: [Sdoi2014]數(shù)表
?
?
Latex的公式寫起來略麻煩。。。
?
設(shè)$\LARGE F(x)=\sum_{d|x} \lfloor \dfrac xd \rfloor$
$\LARGE Answer = \sum_{i=1}^n\sum_{j=1}^{m}F(\gcd(i,j))*[F(\gcd(i,j)<=a]$
?
當(dāng)沒有$a$的限制時
$\LARGE Answer = \sum_{d=1}^{n}\sum_{i=1}^{n}\sum_{j=1}^{m}F(d)*[\gcd(i,j)=d]$
? ? ? ? ? ? ? $\LARGE=\sum_{d=1}^{n}F(d)\sum_{i=1}^{n/d}\sum_{j=1}^{m/d}[\gcd(i,j)=1]$
?
由莫比烏斯反演得(見BZOJ 1101: [POI2007]Zap):
$\LARGE Answer = \sum_{d=1}^{n}F(d)\sum_{i=1}^n\mu(i)\lfloor \dfrac {n}{id} \rfloor?\lfloor \dfrac {m}{id} \rfloor?$
? ? ? ? ? ? $\LARGE =\sum_{d=1}^{n}\lfloor \dfrac nd \rfloor \lfloor \dfrac md \rfloor\sum_{i|d}\mu(\dfrac ni)F(i)$
然后對于?$\LARGE \sum_{d=1}^{n}\lfloor \dfrac nd \rfloor \lfloor \dfrac md \rfloor$可以$O(n\sqrt n)$計(jì)算
后一部分也可以預(yù)先預(yù)處理出來
?
再把$a$的限制加上
離線處理這個問題
將$F$和$a$都排個序,那么要計(jì)算的就是$F(i)<=a$的$i$
那么就可以用樹狀數(shù)組維護(hù)$\LARGE?\sum_{i|d}\mu(\dfrac ni)F(i)$的前綴和,每次插入小于當(dāng)前$a$的$F[i]$,后每次詢問前綴和即可
?
/*BZOJ 3529: [Sdoi2014]數(shù)表樹狀數(shù)組+莫比烏斯反演*/ #include <cstdio> #include <iostream> #include <algorithm>#define rg registerinline void read (int &n) {rg char c = getchar ();for (n = 0; !isdigit (c); c = getchar ());for (; isdigit (c); n = n * 10 + c - '0', c = getchar ()); } #define Max 100000int t[Max + 9], p[Max + 9], mu[Max + 9]; bool is[Max + 9]; inline int min (int a, int b) { return a < b ? a : b; }void Euler (int N) {rg int i, j, k; int C = 0; mu[1] = 1;for (i = 2; i <= N; ++ i){if (!is[i]) p[++ C] = i, mu[i] = -1;for (j = 1; j <= C; ++ j){if ((k = i * p[j]) > N) break;is[k] = true;if (i % p[j] == 0) { mu[k] = 0; break; }else mu[k] = -mu[i];}} }struct Q { int x, y; Q (int a = 0, int b = 0) : x (a), y (b) { } bool operator < (const Q &rhs) const{ return x == rhs.x ? y < rhs.y : x < rhs.x; } } f[Max + 9];void F () {rg int i, j;for (i = 1; i <= Max; ++ i)for (j = i; j <= Max; j += i) f[j].x += i;for (i = 1; i <= Max; ++ i) f[i].y = i;std :: sort (f + 1, f + 1 + Max); }struct D { int n, m, a, id; bool operator < (const D &rhs) const{ return a < rhs.a; } } q[Max + 9]; int Answer[Max + 9];inline int Query (int x) {int res = 0;for (rg int i = x; i; i -= i & (-i))res += t[i];return res; } void Change (int x, int k) { for (rg int i = x; i <= Max; i += i & (-i)) t[i] += k; }int Ask (int N, int M) {int res = 0, j; if (N > M) std :: swap (N, M);for (rg int i = 1; i <= N; i = j + 1){j = min (N / (N / i), M / (M / i));res += (N / i) * (M / i) * (Query (j) - Query (i - 1));}return res & 0x7fffffff; }int main (int argc, char *argv[]) {int N, M; rg int i, j, k;Euler (Max); F ();int T; read (T);for (i = 1; i <= T; ++ i)read (q[i].n), read (q[i].m), read (q[i].a), q[i].id = i;std :: sort (q + 1, q + 1 + T);for (i = 1, j = 1; i <= T; ++ i){for (; j <= Max && f[j].x <= q[i].a; ++ j)for (k = f[j].y; k <= Max; k += f[j].y)Change (k, f[j].x * mu[k / f[j].y]);Answer[q[i].id] = Ask (q[i].n, q[i].m); }for (i = 1; i <= T; ++ i)printf ("%d\n", Answer[i]);return 0; }?
轉(zhuǎn)載于:https://www.cnblogs.com/ZlycerQan/p/8067463.html
總結(jié)
以上是生活随笔為你收集整理的BZOJ 3529: [Sdoi2014]数表的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL COUNT() 函数
- 下一篇: 作业13-网络