D1. Balance (Easy version)
This is the easy version of the problem. The only difference is that in this version there are no "remove" queries.
Initially you have a set containing one element — $0$. You need to handle $q$ queries of the following types:
+ $x$ — add the integer $x$ to the set. It is guaranteed that this integer is not contained in the set;
? $k$ — find the $k\text{-mex}$ of the set.
In our problem, we define the $k\text{-mex}$ of a set of integers as the smallest non-negative integer $x$ that is divisible by $k$ and which is not contained in the set.
Input
The first line contains an integer $q$ $(1 \leq q \leq 2 \cdot {10}^{5})$ — the number of queries.
The following $q$ lines describe the queries.
An addition query of integer $x$ is given in the format + $x$ $(1 \leq x \leq {10}^{18})$. It is guaranteed that $x$ was not contained in the set.
A search query of $k\text{-mex}$ is given in the format ? $k$ $(1 \leq k \leq {10}^{18})$.
It is guaranteed that there will be at least one query of type ? .
Output
For each query of type ? output a single integer — the $k\text{-mex}$ of the set.
Examples
input
15 + 1 + 2 ? 1 + 4 ? 2 + 6 ? 3 + 7 + 8 ? 1 ? 2 + 5 ? 1 + 1000000000000000000 ? 1000000000000000000
output
3 6 3 3 10 3 2000000000000000000
input
6 + 100 ? 100 + 200 ? 100 + 50 ? 50
output
200 300 150
Note
In the first example:
After the first and second queries, the set will contain elements $\{0,1,2\}$. The smallest non-negative number that is divisible by $1$ and is not contained in the set is $3$.
After the fourth query, the set will contain the elements $\{0,1,2,4\}$. The smallest non-negative number that is divisible by $2$ and is not contained in the set is $6$.
In the second example:
- Initially, the set contains only the element $\{0\}$.
- After adding an integer $100$ the set contains elements $\{0,100\}$.
- $100\text{-mex}$ of the set is $200$.
- After adding an integer $200$ the set contains elements $\{0,100,200\}$.
- $100\text{-mex}$ of the set is $300$.
- After adding an integer $50$ the set contains elements $\{0,50,100,200\}$.
- $50\text{-mex}$ of the set is $150$.
解题思路
先想一个最暴力的思路,就是我们用一个哈希表维护集合中存在的数,对于每个询问$k$,我们依次枚举$k$的倍数看看是否出现在哈希表中,直到枚举到某个$k$的倍数在哈希表中不存在。
但这种做法必定会超时,如果依次插入$k$的倍数,然后每次询问都是查询$k$,那么计算量就是$O(n^2)$级别的。因此可以开个哈希表来记录对于某个$k$上一次枚举到哪个数,如果后面再次询问$k$,那么直接从上次枚举的到的数开始往后枚举$k$的倍数就可以了。这是因为对于$\text{mex}$而言,当插入的数越多,$\text{mex}$值只会变大而不会变小。
这种做法的时间复杂度是多少呢?考虑最糟糕的情况,就是依次插入$1 \sim n$,然后依次询问$1 \sim n$,那么计算量大概就是$n + \frac{n}{2} + \frac{n}{3} + \dots + \frac{n}{n} \approx n \log{n}$。
这题卡std::unordered_map和std::unordered_set,因此要么人为手动初始化大小,要么改用std::map和std::set。
AC代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 6 const int N = 1e6 + 10; 7 8 void solve() { 9 int n; 10 scanf("%d", &n); 11 unordered_set<LL> st(N); 12 unordered_map<LL, LL> mp(N); 13 while (n--) { 14 char op[2]; 15 LL x; 16 scanf("%s %lld", op, &x); 17 if (op[0] == '+') { 18 st.insert(x); 19 } 20 else { 21 if (!mp.count(x)) mp[x] = x; 22 while (st.count(mp[x])) { 23 mp[x] += x; 24 } 25 printf("%lld\n", mp[x]); 26 } 27 } 28 } 29 30 int main() { 31 int t = 1; 32 // scanf("%d", &t); 33 while (t--) { 34 solve(); 35 } 36 37 return 0; 38 }
参考资料
Codeforces Round #830 (Div. 2) D1/D2(mex问题):https://zhuanlan.zhihu.com/p/576620849
标签:set,text,leq,version,Easy,integer,100,Balance,mex From: https://www.cnblogs.com/onlyblues/p/16821998.html