RT,调一上午了
树状数组第 k (k∈[−106,106]) 个位置维护当 x=k 是满足的不等式个数
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int Maxn=100000+10;
const int Maxm=2000010;
struct node{
int l,r; // 储存不等式的解集区间
}g[Maxn];
int sum[Maxm];
bool vis[Maxn];
int n,m,q,cnt;
inline int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0' && ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return s*w;
}
inline int lowbit(int x)
{
return x&(-x);
}
void modify(int x,int k)
{
while(x<=n)
sum[x]+=k,x+=lowbit(x);
}
int query(int x)
{
int ret=0;
while(x)
ret+=sum[x],x-=lowbit(x);
return ret;
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
q=read();
n=2000001,m=1000001; // 整体往右平移 m 个位置
while(q--)
{
char s[10];
scanf("%s",s);
if(s[0]=='A')
{
int a=read(),b=read(),c=read();
c-=b,vis[++cnt]=1;
if(a==0)
{
if(c<0)g[cnt].l=1,g[cnt].r=n;
else g[cnt].l=g[cnt].r=0; // l=r=0 表示在范围内无解
}
else
{
if(a>0)
{
g[cnt].l=c/a+1+m;
g[cnt].r=n;
if(g[cnt].l>n)
g[cnt].l=g[cnt].r=0;
if(g[cnt].l<1)
g[cnt].l=1;
}
else
{
g[cnt].r=c/a+m;
if(c%a==0)g[cnt].r--;
g[cnt].l=1;
if(g[cnt].r<1)
g[cnt].l=g[cnt].r=0;
if(g[cnt].r>n)
g[cnt].r=n;
}
}
if(!g[cnt].l)continue;
modify(g[cnt].l,1);
if(g[cnt].r<n)
modify(g[cnt].r+1,-1);
continue;
}
if(s[0]=='D')
{
int pos=read();
if(!vis[pos])continue; // 避免多次删除导致出错
vis[pos]=0;
if(!g[pos].l)continue;
modify(g[pos].l,-1);
if(g[pos].r<n)
modify(g[pos].r+1,1);
}
else
{
int k=read();
printf("%d\n",query(k+m));
}
}
return 0;
}