BZOJ 2762 JLOI 2011 不等式组 树状数组

75 篇文章 1 订阅
49 篇文章 1 订阅

#论我都能想出来的题目#
给出一些不等式,问对于x=k有多少不等式满足要求。
显然一次不等式可以看做一个半数轴或全数轴或空,分别是 x>a,x<a,xR,x
因此这是个区间修改单点查询,使用树状数组即可。
还是尽量排在第一页吧。。

#include <cstdio>
#include <algorithm>
#include <cmath>
#define RANGE 1000000
const int N = 100001;
using namespace std;

int read() {
    int s = 0, f = 1; char ch = getchar();
    for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') f = -1;
    for (; '0' <= ch && ch <= '9'; ch = getchar()) s = s * 10 + ch - '0';
    return s * f;
}

struct BIT {
    int c[2000005];
    int add(int x, int v) {
        x += RANGE + 1;
        for (; x <= 2 * RANGE + 1; x += x & -x) c[x] += v;
    }

    int sum(int x) {
        x += RANGE + 1;
        int s = 0;
        for (; x; x -= x & -x) s += c[x];
        return s;
    }

    void cover(int l, int r, int s) {
        if (l > r) return;
        l = max(l, -RANGE); r = min(r, RANGE);
        add(l, s); add(r + 1, -s);
    }
} bit;

struct Inequation {
    int x, y, c;
    Inequation() { x = y = c = 0; }
    Inequation(int u, int v, int w) {
        c = 0;
        if (u > 0) x = floor((double)(w - v) / u) + 1, y = RANGE;
        else if (u < 0) x = -RANGE, y = ceil((double)(w - v) / u) - 1;
        else if (v > w) x = -RANGE, y = RANGE;
        else x = 2, y = 1;
    }
} e[N];
int main() {
    int t = read(), i = 0, u, v, w; char op[8];
    while (t--) {
        scanf("%s", op);
        if (op[0] == 'A') {
            u = read(); v = read(); w = read();
            e[++i] = Inequation(u, v, w);
            bit.cover(e[i].x, e[i].y, 1);
        } else if (op[0] == 'D') {
            w = read();
            if (!e[w].c)
                e[w].c = 1, bit.cover(e[w].x, e[w].y, -1);
        } else
            printf("%d\n", bit.sum(read()));
    }
    return 0;
}

2762: [JLOI2011]不等式组

Description

旺汪与旺喵最近在做一些不等式的练习。这些不等式都是形如ax+b>c 的一元不等式。当然,解这些不等式对旺汪来说太简单了,所以旺喵想挑战旺汪。旺喵给出一组一元不等式,并给出一个数值 。旺汪需要回答的是x=k 时成立的不等式的数量。聪明的旺汪每次都很快就给出了答案。你的任务是快速的验证旺汪的答案是不是正确的。

Input

输入第一行为一个正整数 ,代表接下来有N 行。
接下来每一行可能有3种形式:
1.“Add a b c”,表明要往不等式组添加一条不等式ax+b>c ;
2.“Del i”,代表删除第i 条添加的不等式(最先添加的是第1条)。
3.“Query k”,代表一个询问,即当x=k 时,在当前不等式组内成立的不等式的数量。
注意一开始不等式组为空,a,b,c,i,k 均为整数,且保证所有操作均合法,不会出现要求删除尚未添加的不等式的情况。

Output

对于每一个询问“Query k”,输出一行,为一个整数,代表询问的答案。

Sample Input

9
Add 1 1 1
Add -2 4 3
Query 0
Del 1
Query 0
Del 2
Query 0
Add 8 9 100
Query 10

Sample Output

1
1
0
0

HINT

第1条添加到不等式组的不等式为x+1>1 ,第2条为-2x+4>3 ,所以第1个询问的时候只有第2条不等式可以成立,故输出1。
然后删除第1条不等式,再询问的时候依然是只有第2条不等式可以成立,故输出1。
再删除第2条不等式后,因为不等式组里面没有不等式了,所以没有不等式可以被满足,故输出0。
继续加入第3条不等式8x+9>100 ,当x=k=10时有8*10+9=89<100,故也没有不等式可以被满足,依然输出0。

数据范围:

20%的数据, N<=1000;
40%的数据, N<=10000;
100%的数据,N<=100000,
a,b,c的范围为[-10^8,10^8],k的范围为[-10^6,10^6]。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值