# weekly-contest-301

## A

### Statement

• amount.length == 3
• 0 <= amount[i] <= 100

You have a water dispenser that can dispense cold, warm, and hot water. Every second, you can either fill up 2 cups with different types of water, or 1 cup of any type of water.

You are given a 0-indexed integer array amount of length 3 where amount[0], amount[1], and amount[2] denote the number of cold, warm, and hot water cups you need to fill respectively. Return the minimum number of seconds needed to fill up all the cups.

Example 1:

Input: amount = [1,4,2]
Output: 4
Explanation: One way to fill up the cups is:
Second 1: Fill up a cold cup and a warm cup.
Second 2: Fill up a warm cup and a hot cup.
Second 3: Fill up a warm cup and a hot cup.
Second 4: Fill up a warm cup.
It can be proven that 4 is the minimum number of seconds needed.

Example 2:

Input: amount = [5,4,4]
Output: 7
Explanation: One way to fill up the cups is:
Second 1: Fill up a cold cup, and a hot cup.
Second 2: Fill up a cold cup, and a warm cup.
Second 3: Fill up a cold cup, and a warm cup.
Second 4: Fill up a warm cup, and a hot cup.
Second 5: Fill up a cold cup, and a hot cup.
Second 6: Fill up a cold cup, and a warm cup.
Second 7: Fill up a hot cup.

Example 3:

Input: amount = [5,0,0]
Output: 5
Explanation: Every second, we fill up a cold cup.

Constraints:

• amount.length == 3
• 0 <= amount[i] <= 100

### Solution

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define endl "\n"
#define fi first
#define se second
#define all(x) begin(x), end(x)
#define rall rbegin(a), rend(a)
#define bitcnt(x) (__builtin_popcountll(x))
#define complete_unique(a) a.erase(unique(begin(a), end(a)), end(a))
#define mst(x, a) memset(x, a, sizeof(x))
#define MP make_pair

using ll = long long;
using ull = unsigned long long;
using db = double;
using ld = long double;
using VLL = std::vector<ll>;
using VI = std::vector<int>;
using PII = std::pair<int, int>;
using PLL = std::pair<ll, ll>;

using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template <typename T, typename S>
inline bool chmax(T &a, const S &b) {
return a < b ? a = b, 1 : 0;
}

template <typename T, typename S>
inline bool chmin(T &a, const S &b) {
return a > b ? a = b, 1 : 0;
}

#ifdef LOCAL
#include <debug.hpp>
#else
#define dbg(...)
#endif

class Solution {
public:
int fillCups(vector<int> &a) {
int res = 0;

while (true) {
sort(all(a));
if (a.back() == 0) {
break;
}

++res;

--a[2];
if (a[1] > 0) {
--a[1];
}
}

return res;
}
};

#ifdef LOCAL

int main() {
return 0;
}

#endif

## B

### Statement

• SmallestInfiniteSet() 初始化 SmallestInfiniteSet 对象以包含 所有 正整数。
• int popSmallest() 移除 并返回该无限集中的最小整数。
• void addBack(int num) 如果正整数 num 存在于无限集中，则将一个 num 添加 到该无限集中。

[[], [2], [], [], [], [1], [], [], []]

[null, null, 1, 2, 3, null, 1, 4, 5]

SmallestInfiniteSet smallestInfiniteSet = new SmallestInfiniteSet();
smallestInfiniteSet.popSmallest(); // 返回 1 ，因为 1 是最小的整数，并将其从集合中移除。
smallestInfiniteSet.popSmallest(); // 返回 2 ，并将其从集合中移除。
smallestInfiniteSet.popSmallest(); // 返回 3 ，并将其从集合中移除。
smallestInfiniteSet.popSmallest(); // 返回 1 ，因为 1 在上一步中被添加到集合中，
// 且 1 是最小的整数，并将其从集合中移除。
smallestInfiniteSet.popSmallest(); // 返回 4 ，并将其从集合中移除。
smallestInfiniteSet.popSmallest(); // 返回 5 ，并将其从集合中移除。

• 1 <= num <= 1000
• 最多调用 popSmallestaddBack 方法 共计 1000

You have a set which contains all positive integers [1, 2, 3, 4, 5, …].

Implement the SmallestInfiniteSet class:

• SmallestInfiniteSet() Initializes the SmallestInfiniteSet object to contain all positive integers.
• int popSmallest() Removes and returns the smallest integer contained in the infinite set.
• void addBack(int num) Adds a positive integer num back into the infinite set, if it is not already in the infinite set.

Example 1:

Input
[[], [2], [], [], [], [1], [], [], []]
Output
[null, null, 1, 2, 3, null, 1, 4, 5]
Explanation
SmallestInfiniteSet smallestInfiniteSet = new SmallestInfiniteSet();
smallestInfiniteSet.popSmallest(); // return 1, since 1 is the smallest number, and remove it from the set.
smallestInfiniteSet.popSmallest(); // return 2, and remove it from the set.
smallestInfiniteSet.popSmallest(); // return 3, and remove it from the set.
smallestInfiniteSet.popSmallest(); // return 1, since 1 was added back to the set and
// is the smallest number, and remove it from the set.
smallestInfiniteSet.popSmallest(); // return 4, and remove it from the set.
smallestInfiniteSet.popSmallest(); // return 5, and remove it from the set.

Constraints:

• 1 <= num <= 1000
• At most 1000 calls will be made in total to popSmallest and addBack.

### Solution

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define endl "\n"
#define fi first
#define se second
#define all(x) begin(x), end(x)
#define rall rbegin(a), rend(a)
#define bitcnt(x) (__builtin_popcountll(x))
#define complete_unique(a) a.erase(unique(begin(a), end(a)), end(a))
#define mst(x, a) memset(x, a, sizeof(x))
#define MP make_pair

using ll = long long;
using ull = unsigned long long;
using db = double;
using ld = long double;
using VLL = std::vector<ll>;
using VI = std::vector<int>;
using PII = std::pair<int, int>;
using PLL = std::pair<ll, ll>;

using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template <typename T, typename S>
inline bool chmax(T &a, const S &b) {
return a < b ? a = b, 1 : 0;
}

template <typename T, typename S>
inline bool chmin(T &a, const S &b) {
return a > b ? a = b, 1 : 0;
}

#ifdef LOCAL
#include <debug.hpp>
#else
#define dbg(...)
#endif

const int N = 1e3 + 5;

class SmallestInfiniteSet {
public:
set<int> s;

SmallestInfiniteSet() {
for (int i = 1; i < N; i++) {
s.insert(i);
}
}

int popSmallest() {
int res = *s.begin();
s.erase(s.begin());
return res;
}

s.insert(num);
}
};

/**
* Your SmallestInfiniteSet object will be instantiated and called as such:
* SmallestInfiniteSet* obj = new SmallestInfiniteSet();
* int param_1 = obj->popSmallest();
*/

#ifdef LOCAL

int main() {
return 0;
}

#endif

## C

### Statement

• 字符 'L''R' 表示片段，其中片段 'L' 只有在其左侧直接存在一个 空位 时才能向 移动，而片段 'R' 只有在其右侧直接存在一个 空位 时才能向 移动。
• 字符 '' 表示可以被 任意 'L''R' 片段占据的空位。

- 将第一个片段向左移动一步，字符串现在变为 "LR__R_" 。
- 将最后一个片段向右移动一步，字符串现在变为 "L___RR" 。
- 将第二个片段向右移动散步，字符串现在变为 "L______RR" 。

• n == start.length == target.length
• 1 <= n <= 105
• starttarget 由字符 'L''R''_' 组成

You are given two strings start and target, both of length n. Each string consists only of the characters 'L', 'R', and '' where:

• The characters 'L' and 'R' represent pieces, where a piece 'L' can move to the left only if there is a blank space directly to its left, and a piece 'R' can move to the right only if there is a blank space directly to its right.
• The character '' represents a blank space that can be occupied by any of the 'L' or 'R' pieces.

Return true if it is possible to obtain the string target by moving the pieces of the string start any number of times. Otherwise, return false.

Example 1:

Input: start = "L__R__R", target = "L______RR"
Output: true
Explanation: We can obtain the string target from start by doing the following moves:
- Move the first piece one step to the left, start becomes equal to "LR__R_".
- Move the last piece one step to the right, start becomes equal to "L___RR".
- Move the second piece three steps to the right, start becomes equal to "L______RR".
Since it is possible to get the string target from start, we return true.

Example 2:

Input: start = "R_L_", target = "__LR"
Output: false
Explanation: The 'R' piece in the string start can move one step to the right to obtain "RL".
After that, no pieces can move anymore, so it is impossible to obtain the string target from start.

Example 3:

Input: start = "R", target = "R"
Output: false
Explanation: The piece in the string start can move only to the right, so it is impossible to obtain the string target from start.

Constraints:

• n == start.length == target.length
• 1 <= n <= 105
• start and target consist of the characters 'L', 'R', and '_'.

### Solution

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <vector>

#define endl "\n"
#define fi first
#define se second
#define all(x) begin(x), end(x)
#define rall rbegin(a), rend(a)
#define bitcnt(x) (__builtin_popcountll(x))
#define complete_unique(a) a.erase(unique(begin(a), end(a)), end(a))
#define mst(x, a) memset(x, a, sizeof(x))
#define MP make_pair

using ll = long long;
using ull = unsigned long long;
using db = double;
using ld = long double;
using VLL = std::vector<ll>;
using VI = std::vector<int>;
using PII = std::pair<int, int>;
using PLL = std::pair<ll, ll>;

using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template <typename T, typename S>
inline bool chmax(T &a, const S &b) {
return a < b ? a = b, 1 : 0;
}

template <typename T, typename S>
inline bool chmin(T &a, const S &b) {
return a > b ? a = b, 1 : 0;
}

#ifdef LOCAL
#include <debug.hpp>
#else
#define dbg(...)
#endif

class Solution {
public:
bool canChange(string s, string t) {
int n = int(s.size());
auto f = vector<pair<char, int>>();
auto g = vector<pair<char, int>>();

for (int i = 0; i < n; i++) {
if (s[i] != '_') {
f.push_back({s[i], i});
}

if (t[i] != '_') {
g.push_back({t[i], i});
}
}

int m = int(f.size());

if (m != int(g.size())) {
return false;
}

for (int i = 0; i < m; i++) {
if (f[i].fi != g[i].fi) {
return false;
}

if (f[i].fi == 'L' && f[i].se < g[i].se) {
return false;
}

if (f[i].fi == 'R' && f[i].se > g[i].se) {
return false;
}
}

return true;
}
};

#ifdef LOCAL

int main() {
return 0;
}

#endif

## D

### Statement

• 每个 arr[i] 都是从 1maxValue 范围内的一个值，其中 0 <= i < n
• 每个 arr[i] 都可以被 arr[i - 1] 整除，其中 0 < i < n

- 以 1 开头的数组（5 个）：[1,1]、[1,2]、[1,3]、[1,4]、[1,5]
- 以 2 开头的数组（2 个）：[2,2]、[2,4]
- 以 3 开头的数组（1 个）：[3,3]
- 以 4 开头的数组（1 个）：[4,4]
- 以 5 开头的数组（1 个）：[5,5]

- 以 1 开头的数组（9 个）：
- 不含其他不同值（1 个）：[1,1,1,1,1]
- 含一个不同值 2（4 个）：[1,1,1,1,2], [1,1,1,2,2], [1,1,2,2,2], [1,2,2,2,2]
- 含一个不同值 3（4 个）：[1,1,1,1,3], [1,1,1,3,3], [1,1,3,3,3], [1,3,3,3,3]
- 以 2 开头的数组（1 个）：[2,2,2,2,2]
- 以 3 开头的数组（1 个）：[3,3,3,3,3]

• 2 <= n <= 104
• 1 <= maxValue <= 104

You are given two integers n and maxValue, which are used to describe an ideal array.

A 0-indexed integer array arr of length n is considered ideal if the following conditions hold:

• Every arr[i] is a value from 1 to maxValue, for 0 <= i < n.
• Every arr[i] is divisible by arr[i - 1], for 0 < i < n.

Return the number of distinct ideal arrays of length n. Since the answer may be very large, return it modulo 109 + 7.

Example 1:

Input: n = 2, maxValue = 5
Output: 10
Explanation: The following are the possible ideal arrays:
- Arrays starting with the value 1 (5 arrays): [1,1], [1,2], [1,3], [1,4], [1,5]
- Arrays starting with the value 2 (2 arrays): [2,2], [2,4]
- Arrays starting with the value 3 (1 array): [3,3]
- Arrays starting with the value 4 (1 array): [4,4]
- Arrays starting with the value 5 (1 array): [5,5]
There are a total of 5 + 2 + 1 + 1 + 1 = 10 distinct ideal arrays.

Example 2:

Input: n = 5, maxValue = 3
Output: 11
Explanation: The following are the possible ideal arrays:
- Arrays starting with the value 1 (9 arrays):
- With no other distinct values (1 array): [1,1,1,1,1]
- With 2nd distinct value 2 (4 arrays): [1,1,1,1,2], [1,1,1,2,2], [1,1,2,2,2], [1,2,2,2,2]
- With 2nd distinct value 3 (4 arrays): [1,1,1,1,3], [1,1,1,3,3], [1,1,3,3,3], [1,3,3,3,3]
- Arrays starting with the value 2 (1 array): [2,2,2,2,2]
- Arrays starting with the value 3 (1 array): [3,3,3,3,3]
There are a total of 9 + 1 + 1 = 11 distinct ideal arrays.

Constraints:

• 2 <= n <= 104
• 1 <= maxValue <= 104

### Solution

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <vector>

#define endl "\n"
#define fi first
#define se second
#define all(x) begin(x), end(x)
#define rall rbegin(a), rend(a)
#define bitcnt(x) (__builtin_popcountll(x))
#define complete_unique(a) a.erase(unique(begin(a), end(a)), end(a))
#define mst(x, a) memset(x, a, sizeof(x))
#define MP make_pair

using ll = long long;
using ull = unsigned long long;
using db = double;
using ld = long double;
using VLL = std::vector<ll>;
using VI = std::vector<int>;
using PII = std::pair<int, int>;
using PLL = std::pair<ll, ll>;

using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template <typename T, typename S>
inline bool chmax(T &a, const S &b) {
return a < b ? a = b, 1 : 0;
}

template <typename T, typename S>
inline bool chmin(T &a, const S &b) {
return a > b ? a = b, 1 : 0;
}

#ifdef LOCAL
#include <debug.hpp>
#else
#define dbg(...)
#endif

const int mod = 1e9 + 7;

namespace linear_seq {
typedef long long ll;
typedef vector<ll> VI;
#define rep(i, a, n) for (ll i = a; i < n; i++)
#define pb push_back
#define SZ(x) ((int)(x).size())
ll powmod(ll a, ll b) {
ll res = 1;
a %= mod;
assert(b >= 0);
for (; b; b >>= 1) {
if (b & 1)
res = res * a % mod;
a = a * a % mod;
}
return res;
}
const ll mod = 1e9 + 7;
const int N = 1e5 + 10;
ll res[N], base[N], _c[N], _md[N];
vector<ll> Md;
void mul(ll *a, ll *b, ll k) {
rep(i, 0, k + k) _c[i] = 0;
rep(i, 0, k) if (a[i]) rep(j, 0, k) _c[i + j] = (_c[i + j] + a[i] * b[j]) % mod;
for (ll i = k + k - 1; i >= k; i--)
if (_c[i])
rep(j, 0, SZ(Md)) _c[i - k + Md[j]] = (_c[i - k + Md[j]] - _c[i] * _md[Md[j]]) % mod;
rep(i, 0, k) a[i] = _c[i];
}
// a 系数 b 初值 b[n+1]=a[0]*b[n]+...
ll solve(ll n, VI a, VI b) {
ll ans = 0, pnt = 0;
ll k = SZ(a);
assert(SZ(a) == SZ(b));
rep(i, 0, k) _md[k - 1 - i] = -a[i];
_md[k] = 1;
Md.clear();
rep(i, 0, k) if (_md[i] != 0) Md.push_back(i);
rep(i, 0, k) res[i] = base[i] = 0;
res[0] = 1;
while ((1ll << pnt) <= n) pnt++;
for (ll p = pnt; p >= 0; p--) {
mul(res, res, k);
if ((n >> p) & 1) {
for (ll i = k - 1; i >= 0; i--) res[i + 1] = res[i];
res[0] = 0;
rep(j, 0, SZ(Md)) res[Md[j]] = (res[Md[j]] - res[k] * _md[Md[j]]) % mod;
}
}
rep(i, 0, k) ans = (ans + res[i] * b[i]) % mod;
if (ans < 0)
ans += mod;
return ans;
}
VI BM(VI s) {
VI C(1, 1), B(1, 1);
ll L = 0, m = 1, b = 1;
rep(n, 0, SZ(s)) {
ll d = 0;
rep(i, 0, L + 1) d = (d + (ll)C[i] * s[n - i]) % mod;
if (d == 0)
++m;
else if (2 * L <= n) {
VI T = C;
ll c = mod - d * powmod(b, mod - 2) % mod;
while (SZ(C) < SZ(B) + m) C.pb(0);
rep(i, 0, SZ(B)) C[i + m] = (C[i + m] + c * B[i]) % mod;
L = n + 1 - L;
B = T;
b = d;
m = 1;
} else {
ll c = mod - d * powmod(b, mod - 2) % mod;
while (SZ(C) < SZ(B) + m) C.pb(0);
rep(i, 0, SZ(B)) C[i + m] = (C[i + m] + c * B[i]) % mod;
++m;
}
}
return C;
}
ll gao(VI a, ll n) {
VI c = BM(a);
c.erase(c.begin());
rep(i, 0, SZ(c)) c[i] = (mod - c[i]) % mod;
return solve(n, c, VI(a.begin(), a.begin() + SZ(c)));
}
};  // namespace linear_seq

class Solution {
public:
int idealArrays(int n, int maxValue) {
const int N = 100;
auto f = vector<vector<int>>(N + 1, vector<int>(maxValue + 5, 0));

for (int i = 1; i <= maxValue; i++) {
f[1][i] = 1;
}

for (int i = 1; i < N; i++) {
auto &cur = f[i];
auto &nx = f[i + 1];

for (int j = 1; j <= maxValue; j++) {
for (int k = 1; j * k <= maxValue; k++) {
nx[j * k] += cur[j];
nx[j * k] %= mod;
}
}
}

auto g = vector<ll>();

for (int i = 1; i <= N; i++) {
g.push_back(0);
for (int j = 1; j <= maxValue; j++) {
g.back() += f[i][j];
g.back() %= mod;
}
}

if (n <= N) {
return g[n - 1];
}

return int(linear_seq::gao(g, n - 1));
}
};

#ifdef LOCAL

int main() {
{
auto s = Solution();
auto res = s.idealArrays(10000, 10000);
dbg(res);
}

return 0;
}

#endif