ABC 选做(2000<=Difficulty<3200)

ABC003D(Difficulty:2033)

部分分 $D+L=X\times Y$ 答案显然为 $(R-X+1)\times (C-Y+1)\times\dbinom{X\times Y}{D}$。

考虑分成没有卡到上方、下方、左侧、右侧的四个集合,容斥出答案即可,代码用四位二进制数实现比较简单。

 1 const int N = 910;
 2 const ll p = 1e9 + 7;
 3 int r, c, x, y, d, l;
 4 ll ans, binom[N][N];
 5 
 6 inline void addmod(ll &x, ll y) { x += y; if (x >= p) x -= p; }
 7 inline void submod(ll &x, ll y) { x -= y; if (x < 0) x += p; }
 8 
 9 int main()
10 {
11     read(r, c, x, y, d, l);
12     for (int i = 0; i <= x * y; ++i)
13     {
14         binom[i][0] = 1;
15         for (int j = 1; j <= i; ++j)
16             addmod(binom[i][j], binom[i - 1][j] + binom[i - 1][j - 1]);
17     }
18     for (int i = 0; i < 16; ++i)
19     {
20         int xx = x, yy = y;
21         if (i >> 0 & 1) --xx;
22         if (i >> 1 & 1) --xx;
23         if (i >> 2 & 1) --yy;
24         if (i >> 3 & 1) --yy;
25         if (xx <= 0 || yy <= 0) continue;
26         if (__builtin_popcount(i) & 1)
27             submod(ans, binom[xx * yy][d + l] * binom[d + l][d] % p);
28         else addmod(ans, binom[xx * yy][d + l] * binom[d + l][d] % p);
29     }
30     ans = ans * (r - x + 1) % p * (c - y + 1) % p; print(ans, '\n');
31     flush_pbuf(); return 0;
32 }
View Code

ABC008D(Difficulty:2203)

$2^{30}\approx10^9$,时限还开到 4s,直接暴力记搜就完了,注意 $O(\log)$ 存状态被卡了,需要手写 hash 表 $O(1)$ 存状态。

理论上状态量很大,实际上根本跑不满,这份代码最慢的点 40-ms 就冲过去了,所以这题是不是可以加强到 $n\le35$ 时限 2s 啊/se

 1 const int N = 35;
 2 int w, h, n, x[N], y[N];
 3 struct node
 4 {
 5     int _x1, _y1, _x2, _y2;
 6     node() {}
 7     node(int a, int b, int c, int d) : _x1(a), _y1(b), _x2(c), _y2(d) {}
 8     inline bool operator == (const node &x) const
 9     {
10         return _x1 == x._x1 && _y1 == x._y1 && _x2 == x._x2 && _y2 == x._y2;
11     }
12 };
13 
14 struct hash_table
15 {
16     static const int P = 1e7 + 19;
17     const ll b1 = 131, b2 = b1 * b1, b3 = b2 * b1;
18     int tot, h[P];
19     struct data
20     {
21         node x; ll val; int nxt;
22         data() {}
23         data(node _x, ll _val, int _nxt) : x(_x), val(_val), nxt(_nxt) {}
24     } e[P << 1];
25     
26     inline void clear() { tot = 0, memset(h, 0, sizeof(h)); }
27     inline int hash(node x) { return (x._x1 * b3 + x._y1 * b2 + x._x2 * b1 + x._y2) % P; }
28     
29     inline ll& operator [] (node x)
30     {
31         int pos = hash(x);
32         for (int i = h[pos]; i; i = e[i].nxt)
33             if (e[i].x == x) return e[i].val;
34         e[++tot] = data(x, -1, h[pos]), h[pos] = tot;
35         return e[tot].val;
36     }
37 } Map;
38 
39 ll dfs(int _x1, int _y1, int _x2, int _y2)
40 {
41     if (_x1 > _x2 || _y1 > _y2) return 0;
42     node a = node(_x1, _y1, _x2, _y2);
43     if (~Map[a]) return Map[a];
44     for (int i = 1; i <= n; ++i)
45         if (_x1 <= x[i] && x[i] <= _x2 && _y1 <= y[i] && y[i] <= _y2)
46         {
47             Map[a] = Max(Map[a], dfs(_x1, _y1, x[i] - 1, y[i] - 1) +
48             dfs(_x1, y[i] + 1, x[i] - 1, _y2) + dfs(x[i] + 1, _y1, _x2, y[i] - 1) +
49             dfs(x[i] + 1, y[i] + 1, _x2, _y2) + _x2 - _x1 + _y2 - _y1 + 1);
50         }
51     return Max(Map[a], 0ll);
52 }
53 
54 int main()
55 {
56     read(w, h, n);
57     for (int i = 1; i <= n; ++i) read(x[i], y[i]);
58     print(dfs(1, 1, w, h), '\n');
59     flush_pbuf(); return 0;
60 }
View Code

ABC009D(Difficulty:2213)

将 AND 视作乘法,将 XOR 视作加法,$k\le100,\ m\le10^9$,显然是矩阵快速幂。

单位矩阵为:

$$ \begin{bmatrix} 2^{32}-1 & 0 & \cdots & 0 & 0 \\ 0 & 2^{32}-1 & \cdots & 0 & 0 \\ \vdots & \vdots & \ddots & \vdots & \vdots \\ 0 & 0 & \cdots & 2^{32}-1 & 0 \\ 0 & 0 & \cdots & 0 & 2^{32}-1 \end{bmatrix} $$

公式为:

$$ \begin{bmatrix} c_1 & c_2 & \cdots & c_{k-2} & c_{k-1} & c_k \\ 2^{32}-1 & 0 & \cdots & 0 & 0 & 0 \\ 0 & 2^{32}-1 & \cdots & 0 & 0 & 0 \\ \vdots & \vdots & \ddots & \vdots & \vdots & \vdots \\ 0 & 0 & \cdots & 2^{32}-1 & 0 & 0 \\ 0 & 0 & \cdots & 0 & 2^{32}-1 & 0 \end{bmatrix}^{m-k} \cdot \begin{bmatrix} a_k \\ a_{k-1} \\ a_{k-2} \\ \vdots \\ a_2 \\ a_1 \end{bmatrix} = \begin{bmatrix} a_{m} \\ a_{m-1} \\ a_{m-2} \\ \vdots \\ a_{m-k+2} \\ a_{m-k+1} \end{bmatrix}$$

注意特判 $m\le k$ 的情况。

 1 const int N = 105;
 2 const unsigned int I = -1;
 3 int n, m;
 4 unsigned int a[N], c[N];
 5 struct matrix
 6 {
 7     unsigned int a[N][N];
 8     matrix() { clear(); }
 9     inline void clear() { memset(a, 0, sizeof(a)); }
10     inline void init()
11     {
12         for (int i = 1; i <= n; ++i)
13             for (int j = 1; j <= n; ++j)
14                 i == j ? a[i][j] = I : a[i][j] = 0;
15     }
16 } f, g;
17 inline matrix operator * (const matrix &x, const matrix &y)
18 {
19     matrix res;
20     for (int i = 1; i <= n; ++i)
21         for (int k = 1; k <= n; ++k)
22             for (int j = 1; j <= n; ++j)
23                 res.a[i][j] ^= x.a[i][k] & y.a[k][j];
24     return res;        
25 }
26 inline matrix power(matrix x, int y)
27 {
28     matrix res; res.init();
29     for (; y; y >>= 1, x = x * x)
30         if (y & 1) res = res * x;
31     return res;
32 }
33 
34 int main()
35 {
36     read(n, m);
37     for (int i = 1; i <= n; ++i) read(a[i]);
38     for (int i = 1; i <= n; ++i) read(c[i]);
39     if (m <= n) { print(a[m], '\n'); flush_pbuf(); return 0; }
40     for (int i = 1; i <= n; ++i)
41     {
42         f.a[1][i] = c[i];
43         if (i < n) f.a[i + 1][i] = I;
44         g.a[n - i + 1][1] = a[i];
45     }
46     f = power(f, m - n), g = f * g;
47     print(g.a[1][1], '\n');
48     flush_pbuf(); return 0;
49 }
View Code

ABC020D(Difficulty:2695)

推一下柿子:

$$ \begin{split} &  \sum\limits_{i=1}^n \operatorname{lcm}(i,k) \\ = & \sum\limits_{i=1}^n \dfrac{i\cdot k}{\gcd(i,k)} \\ = & k \sum\limits_{i=1}^n \dfrac{i}{d} \cdot [\gcd(i,k)=d] \\ = & k \sum\limits_{d\mid k} \sum\limits_{i=1}^{\frac{n}{d}} i \cdot [\gcd(i,\frac{k}{d})=1] \end{split} $$

因此问题转化为给定 $m,d$ 求 $\sum\limits_{i=1}^m i\cdot [\gcd(i,d)=1]$,容斥即可。

总时间复杂度上界为 $O(\sqrt{k}+d(k)\cdot 2^{\omega(k)}\cdot \omega(k))$,实际上根本跑不满。

 1 const ll p = 1e9 + 7;
 2 vector<int> d, omega;
 3 
 4 inline void get_d(int k)
 5 {
 6     for (int i = 1; i * i <= k; ++i)
 7         if (!(k % i))
 8         {
 9             d.emplace_back(i);
10             if (i != k / i) d.emplace_back(k / i);
11         }
12 }
13 inline void get_omega(int k)
14 {
15     for (int i = 2; i * i <= k; ++i)
16         if (!(k % i))
17         {
18             omega.emplace_back(i);
19             while (!(k % i)) k /= i;
20         }
21     if (k > 1) omega.emplace_back(k);
22 }
23 
24 inline void addmod(ll &x, ll y) { x += y; if (x >= p) x -= p; }
25 inline void submod(ll &x, ll y) { x -= y; if (x < 0) x += p; }
26 
27 inline ll solve(int n, int k)
28 {
29     vector<int>().swap(omega); get_omega(k); ll res = 0;
30     for (int i = 0; i < 1 << omega.size(); ++i)
31     {
32         int GCD = 1;
33         for (int j = 0; j < omega.size(); ++j)
34             if (i >> j & 1) GCD *= omega[j];
35         ll cnt = (n / GCD + 1ll) * (n / GCD) / 2; cnt %= p;
36         if (__builtin_popcount(i) & 1) submod(res, cnt * GCD % p);
37         else addmod(res, cnt * GCD % p);
38     }
39     return res;
40 }
41 
42 int main()
43 {
44     int n, k; ll ans = 0; read(n, k); get_d(k);
45     for (int i = 0; i < d.size(); ++i)
46         addmod(ans, solve(n / d[i], k / d[i]) * k % p);
47     print(ans, '\n');
48     flush_pbuf(); return 0;
49 }
View Code

ABC024D(Difficulty:2050)

设 $a=\dfrac{A}{B}=\dfrac{\binom{n+m}{n}}{\binom{n+m+1}{n}}=\dfrac{m+1}{n+m+1},\ b=\dfrac{A}{C}=\dfrac{\binom{n+m}{n}}{\binom{n+m+1}{m}}=\dfrac{n+1}{n+m+1}$。

由此解出 $n=\dfrac{a-1}{-a-b+1},\ m=\dfrac{b-1}{-a-b+1}$。

 1 const ll p = 1e9 + 7;
 2 
 3 inline ll power(ll x, ll y)
 4 {
 5     ll res = 1;
 6     for (; y; y >>= 1, x = x * x % p)
 7         if (y & 1) res = res * x % p;
 8     return res;
 9 }
10 
11 int main()
12 {
13     ll A, B, C, a, b, n, m; read(A, B, C);
14     a = A * power(B, p - 2) % p, b = A * power(C, p - 2) % p;
15     n = (a - 1) * power(-a - b + 1, p - 2) % p; if (n < 0) n += p;
16     m = (b - 1) * power(-a - b + 1, p - 2) % p; if (m < 0) m += p;
17     print(n, ' ', m, '\n');
18     flush_pbuf(); return 0;
19 }
View Code

ABC025D(Difficulty:3006)

ABC027D(Difficulty:2088)

ABC033D(Difficulty:2248)

To be continued...

posted @ 2022-03-13 16:41  jhqqwq  阅读(69)  评论(0编辑  收藏  举报