bzoj 2762: [JLOI2011]不等式组——树状数组

旺汪与旺喵最近在做一些不等式的练习。这些不等式都是形如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]。

——————————————————————————————————

这道题有毒QAQ 感觉大佬博客提醒 神犇传送门

这题一堆坑点

1. a可能为0 那么这个时候如果b>c那么x取任意值都有解 否则无解

2. x有两种形式 x>y 或者 x<y 

分类讨论之后 x>y的形式为 x>=floor(y)+1 x<y的形式为 x<=ceil(y)-1 这里不要加EPS否则就gg了QAQ

3.x的取值范围可能超过[-1000000,1000000]

4.由于有负数 所以区间修改时左右端点都要加上1000001 若加上1000000则死循环

5.很坑的一点是数据虽然说保证合法但是我们可以无视这句话了…… 有重复删除的不等式 需要记录

那么这些细节处理完之后就是简单的差分辣

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
const int mx=1e6;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,cnt,f[mx];
int s[mx<<1|0xffff];
struct pos{int l,r;}q[mx];
char ch[15];
pos find(int a,int b,int c){
    if(!a){
        if(b>c) return (pos){-mx,mx};
        else return (pos){1,0};
    }
    else if(a>0){
        int p=floor(double(c-b)/a+1);
        if(p<-mx) return (pos){-mx,mx};
        else if(p>mx) return (pos){1,0};
        return (pos){p,mx};
    }
    else{
        int p=ceil(double(c-b)/a-1);  
        if(p>mx) return (pos){-mx,mx};
        else if(p<-mx) return (pos){1,0};
        return (pos){-mx,p};
    }
}
int a,b,c;
#define lowbit(x) x&-x
void ins(int x,int v){while(x<=mx*2+1) s[x]+=v,x+=lowbit(x);}
int query(int x){
    int sum=0;
    while(x) sum+=s[x],x-=lowbit(x);
    return sum;
}
void modify(pos x,int s){ins(x.l+1+mx,s);ins(x.r+2+mx,-s);}
int main(){
    n=read();
    for(int i=1;i<=n;i++){
        scanf("%s",ch);
        if(ch[0]=='A'){
            a=read(); b=read(); c=read();
            q[++cnt]=find(a,b,c);
            modify(q[cnt],1);
        }
        else if(ch[0]=='Q') b=read(),printf("%d
",query(b+mx+1));
        else if(ch[0]=='D'){
            b=read(); if(f[b]) continue;
            f[b]=1; modify(q[b],-1);
        }
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/lyzuikeai/p/7665743.html