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