AB水题,

C - Tsundoku

有两摞书,一摞有 $n$ 本,从上至下每本需阅读 $a_i$ 分钟,一摞有 $m$ 本,从上至下每本需阅读 $b_i$ 分钟,问最多能在 $k$ 分钟内读多少本书。

挺明显的前缀和处理,枚举从第一摞书中读多少本,余下的时间用二分查找能在第二摞书中读多少本。

  1. ll n, m, k, a[1 << 18], b[1 << 18];
  2. int main() {
  3. cin.tie(nullptr)->sync_with_stdio(false);
  4. cin >> n >> m >> k;
  5. for (int i = 1; i <= n; ++i) cin >> a[i], a[i] += a[i - 1];
  6. for (int i = 1; i <= m; ++i) cin >> b[i], b[i] += b[i - 1];
  7. ll cnt = 0;
  8. for (ll i = 0; i <= n; ++i)
  9. if (k >= a[i]) cnt = max(cnt, upper_bound(b + 1, b + m + 1, k - a[i]) - b - 1 + i);
  10. cout << cnt;
  11. }

D - Sum of Divisors

设 $f{(x)}$ 为 $x$ 正因子个数,计算 $\sum\limits{i = 1}^n i\times f_{x}$

先筛出每个数的 AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图1%7D#card=math&code=f_%7B%28x%29%7D) 然后累加起来

  1. const int N = 1e7 + 10;
  2. ll a[N], n ,cnt;
  3. int main() {
  4. cin.tie(nullptr)->sync_with_stdio(false);
  5. cin >> n;
  6. for (int i = 1; i <= n; ++i) for (int j = i; j <= n; j += i) a[j] += 1;
  7. for (int i = 1; i <= n; ++i) cnt += i * a[i];
  8. cout << cnt;
  9. }

E - NEQ

给出 $n,m$ 计算有多少个大小为 $n$ 的子序列 $a,b$ 满足以下条件
1.$1 \le a_i,b_i \le m$
2.$a_i \not= a_j if\ i\not= j$
3.$b_i \not= b_j if\ i\not= j$
4.$a_i \not= b_i$

没想出来,参考了一下其他的思路:

AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图2%5EiCn%5EiA%7Bm%20-%20i%7D%5E%7Bn%20-%20i%7D)%0A#card=math&code=Am%5En%28%5Csum%7Bi%20%3D%200%7D%5En%28-1%29%5EiCn%5EiA%7Bm%20-%20i%7D%5E%7Bn%20-%20i%7D%29%0A)

  • AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图3AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图4 个数排 AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图5 个位置,即合法的 AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图6 的个数;
  • AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图7,对于每个合法的 AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图8 来说,合法的 AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图9 的个数;

    • AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图10%5Ei#card=math&code=%28-1%29%5Ei),由容斥定理;
    • AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图11 ,从 AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图12AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图13 个位置中选 AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图14 个位置与 AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图15 中的数相等,余下 AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图16 个位置共有 AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图17 个数可选;

      • AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图18AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图19 ,即合法 AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图20 的个数;
      • AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图21AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图22 ,即代表对 AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图23 来说不合法 AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图24 的个数;
      • 所以右式即用容斥原理从合法的 AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图25 中减去对 AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图26 来说不合法的 AtCoder Beginner Contest 172 (C题前缀和   二分,D题筛因子,E题容斥定理) - 图27 的个数。
  1. using ll = long long;
  2. const int N = 5e5 + 10, mod = 1e9 + 7;
  3. ll fac[N];
  4. ll qpow(ll a, ll b) {
  5. ll ans = 1;
  6. for (; b; b >>= 1, a = a * a % mod)if (b & 1) ans = ans * a % mod;
  7. return ans;
  8. }
  9. void init() {
  10. fac[0] = 1;
  11. for (int i = 1; i < N; ++i) fac[i] = fac[i - 1] * i % mod;
  12. }
  13. ll inv(ll n) {return qpow(n, mod - 2);}
  14. ll A(ll n, ll m) {return fac[n] * inv(fac[n - m]) % mod;}
  15. ll C(ll n, ll m) {return fac[n] * inv(fac[m]) % mod * inv(fac[n - m]) % mod;}
  16. int main() {
  17. cin.tie(nullptr)->sync_with_stdio(false);
  18. init();
  19. int n, m; cin >> n >> m;
  20. ll sum = 0;
  21. for (int i = 0; i <= n; ++i) {
  22. sum += qpow(-1, i) * C(n, i) * A(m - i, n - i) % mod;
  23. sum = (sum + mod) % mod;
  24. }
  25. cout << A(m, n) * sum % mod;
  26. }