• 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
  • 相关阅读:
    Linux 实用指令(5)--组管理和权限管理
    Linux 实用指令(4)
    Linux用户管理 (3)
    Oracle如何用单字段或多字段进行查重
    SQL中的左连接与右连接,内连接有什么不同
    Markdown语法--整理
    应用程序无法正常启动0xc000007b
    Linux开机、重启和用户登录注销(2)
    Linux vi和vim编辑器(1)
    SecureCRT 64位 破解版和安装,以及解决乱码问题
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7665743.html
Copyright © 2020-2023  润新知