【BZOJ2762】[JLOI2011]不等式组(树状数组)

题目:

BZOJ2762

分析:

加入的不等式分三种情况
\(a>0\),可以变成\(x>\lfloor \frac{c-b}{a}\rfloor\)
\(a=0\),若\(b>c\)则恒成立,否则恒不成立
\(a<0\),可以变成\(x<\lceil \frac{c-b}{a}\rceil\)

对于\(a=0\),用一个变量\(sum\)记一下当前有多少不等式恒成立,删除的时候注意要维护\(sum\)

对于\(a\neq0\),可以开两个权值树状数组\(greater\)\(less\)记录。当加入\(a>0\)时,令\(x=\lfloor \frac{c-b}{a}\rfloor\),给\(greater\)\(x\)位置加\(1\),查询时查\([0,k)\)区间的和。\(a<0\)时在\(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();
}

猜你喜欢

转载自www.cnblogs.com/zyt1253679098/p/9694972.html