CF1732D2 Balance (Hard version) 题解
前天打了波CF结果怒掉100分,果然退化得太厉害了,遂于昨晚补题.
题面
维护一个集合 SS ,有三种操作:插入一个数、删除一个数、查询 kk 的倍数中没出现过的最小的数。
思路
考试的时候想了一个瞎jb倍增的做法,结果显然是错的(悲)
赛后想了个貌似复杂度不对的算法(能过就行,甚至还比大部分人快).
就是对每一个数x,在询问它的时候更新与x对应的一个集合exist(用map实现),这个集合维护已经在当前插入的数中(记为S)有的x的倍数(但是这个貌似根本只需要一个vector就行了,因为保证他有序)
对于一个x,查询的mex要不然在比之前exist中最大的元素大的最小的那一个里面,要不然就在被删除的exist元素中,逐一对比即可.
D.cpp
#include <cmath>
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <set>
#define int long long
#define PRINT_SET(x) \
cout<<"SET_VALUE:"<<endl;\
for(set<int>::iterator i=x.begin();i!=x.end();++i) \
cout<<*i<<' ';\
cout<<endl<<"END"<<endl;
using namespace std;
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
inline void write(int a)
{
if (a < 0)
{
putchar('-');
putchar('1');
}
else
{
if (a >= 10)
write(a / 10);
putchar(a % 10 + '0');
}
}
const int maxn = 100005, mod = 998244353;
int q;
set<int> S, del;
map<int, set<int>> exist;
signed main()
{
/* freopen("D.out","w",stdout); */
S.insert(0);
q = read();
while (q--)
{
/* cout<<"S"<<endl;
PRINT_SET(S);
cout<<"del"<<endl;
PRINT_SET(del); */
char ch;
cin >> ch;
int x = read();
if (ch == '+')
{
S.insert(x);
if (del.find(x) != del.end())
{
del.erase(x);
}
}
else if (ch == '-')
{
del.insert(x);
S.erase(x);
}
else
{
int res = 0, flag = 0;
set<int> &ex = exist[x];
set<int>::iterator ex_i = ex.begin(), exend = ex.end();
set<int>::iterator del_i = del.begin(), delend = del.end();
while (ex_i != exend && del_i != delend)
{
ex_i = ex.lower_bound(*del_i);
if (ex_i != exend && *ex_i == *del_i)
{
res = *ex_i;
/* ex.erase(res); */
flag = 1;
break;
}
del_i = del.lower_bound(*ex_i);
}
if (flag)
{
write(res), puts("");
continue;
}
int maxx=0;
if(!ex.empty())
maxx=*ex.rbegin()+x;
set<int>::iterator Send = S.end();
for(int i=maxx;;i+=x)
{
if(S.find(i)==Send)
{
res=i;
break;
}
else
{
ex.insert(i);
}
}
write(res), puts("");
}
}
return 0;
}
/*
3
+ 1
- 1
? 2
*/
/*
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
? 2
- 1
- 3
- 6
+ 6
? 2
- 6
? 2
*/
看起来确实可以用vector,常数--
D.cpp
#include <cmath>
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#define int long long
#define PRINT_SET(x) \
cout << "SET_VALUE:" << endl; \
for (set<int>::iterator i = x.begin(); i != x.end(); ++i) \
cout << *i << ' '; \
cout << endl \
<< "END" << endl;
using namespace std;
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
inline void write(int a)
{
if (a < 0)
{
putchar('-');
putchar('1');
}
else
{
if (a >= 10)
write(a / 10);
putchar(a % 10 + '0');
}
}
const int maxn = 100005, mod = 998244353;
int q;
set<int> S, del;
map<int, vector<int>> exist;
signed main()
{
/* freopen("D.out","w",stdout); */
S.insert(0);
q = read();
while (q--)
{
/* cout<<"S"<<endl;
PRINT_SET(S);
cout<<"del"<<endl;
PRINT_SET(del); */
char ch;
cin >> ch;
int x = read();
if (ch == '+')
{
S.insert(x);
if (del.find(x) != del.end())
{
del.erase(x);
}
}
else if (ch == '-')
{
del.insert(x);
S.erase(x);
}
else
{
int res = 0, flag = 0;
vector<int> &ex = exist[x];
vector<int>::iterator ex_i = ex.begin(), exend = ex.end();
set<int>::iterator del_i = del.begin(), delend = del.end();
while (ex_i != exend && del_i != delend)
{
ex_i = lower_bound(ex_i, exend, *del_i);
if (ex_i != exend && *ex_i == *del_i)
{
res = *ex_i;
/* ex.erase(res); */
flag = 1;
break;
}
del_i = del.lower_bound(*ex_i);
}
if (flag)
{
write(res), puts("");
continue;
}
int maxx = 0;
if (!ex.empty())
maxx = *ex.rbegin() + x;
set<int>::iterator Send = S.end();
for (int i = maxx;; i += x)
{
if (S.find(i) == Send)
{
res = i;
break;
}
else
{
ex.insert(ex.end(),i);
}
}
write(res), puts("");
}
}
return 0;
}
/*
3
+ 1
- 1
? 2
*/
/*
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
? 2
- 1
- 3
- 6
+ 6
? 2
- 6
? 2
*/
EntyEnty520~