题目:
分析:
加入的不等式分三种情况
当
a
>
0
a>0
a>0,可以变成
x
>
⌊
c
−
b
a
⌋
x>\lfloor \frac{c-b}{a}\rfloor
x>⌊ac−b⌋
当
a
=
0
a=0
a=0,若
b
>
c
b>c
b>c则恒成立,否则恒不成立
当
a
<
0
a<0
a<0,可以变成
x
<
⌈
c
−
b
a
⌉
x<\lceil \frac{c-b}{a}\rceil
x<⌈ac−b⌉
对于 a = 0 a=0 a=0,用一个变量 s u m sum sum记一下当前有多少不等式恒成立,删除的时候注意要维护 s u m sum sum。
对于 a ≠ 0 a\neq0 a̸=0,可以开两个权值树状数组 g r e a t e r greater greater和 l e s s less less记录。当加入 a > 0 a>0 a>0时,令 x = ⌊ c − b a ⌋ x=\lfloor \frac{c-b}{a}\rfloor x=⌊ac−b⌋,给 g r e a t e r greater greater的 x x x位置加 1 1 1,查询时查 [ 0 , k ) [0,k) [0,k)区间的和。 a < 0 a<0 a<0时在 l e s s less less上类似。
对于删除操作,在树状数组上删除该不等式贡献的值即可。注意要记录已删除的不等式防止重复删除。
代码:
这题思路简单,但是代码细节比较多……
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
namespace zyt
{
const int DELETED = 1e9, P = 1e6 + 10, OPT = 1e5 + 10, N = P * 2;
class Tree_Array
{
private:
int data[N];
inline int lowbit(const int x)
{
return x & -x;
}
public:
Tree_Array()
{
memset(data, 0, sizeof(data));
}
inline void add(int a, const int x)
{
while (a < N)
data[a] += x, a += lowbit(a);
}
inline int query(int a)
{
int ans = 0;
while (a > 0)
ans += data[a], a -= lowbit(a);
return ans;
}
}less, greater;
int n;
pair<int, int> opt[OPT];
int cnt, sum;
int work()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> n;
for (int i = 0; i < n; i++)
{
string s;
cin >> s;
if (s == "Add")
{
int a, b, c, x;
cin >> a >> b >> c;
if (a == 0)
{
opt[++cnt] = make_pair(0, (bool)(b > c));
if (b > c)
sum++;
}
else if (a < 0)
{
x = (int)(ceil((c - b) / (double)a) + P);
if (x < 1)
x = 1;
if (x >= N)
x = N - 1;
opt[++cnt] = make_pair(-1, x);
less.add(x, 1);
}
else
{
x = (int)(floor((c - b) / (double)a) + P);
if (x < 1)
x = 1;
if (x >= N)
x = N - 1;
opt[++cnt] = make_pair(1, x);
greater.add(x, 1);
}
}
else if (s == "Del")
{
int a;
cin >> a;
if (opt[a].first == 0)
sum -= (opt[a].second == 1);
else if (opt[a].second != DELETED)
{
if (opt[a].first == -1)
less.add(opt[a].second, -1);
else
greater.add(opt[a].second, -1);
}
opt[a].second = DELETED;
}
else
{
int a;
cin >> a;
a += P;
cout << sum + greater.query(a - 1) + less.query(N - 1) - less.query(a) << '\n';
}
}
return 0;
}
}
int main()
{
return zyt::work();
}