P5482 [JLOI2011]不等式组

Jennie

似乎对于每一个不等式,都是有一个阈值k,那么分类讨论a的符号,也就是不等式的方向,因为输入的key的大小不超过\(10^6\),那么一些算出来的key可以知道肯定满足、不满足

然后呢,根据不等式的方向扔到两个树状数组,查询即可

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m;
int tr[2000008][2];
int maxn=1000001;
int a,b,c;
int cnt;
int x,y,z;
int vis[100005];
int sit[100005];
int mu;
int ke[100005];
int lowbit(int x){
	return x&-x;
}
void add(int x,int v,int ex){
	x+=maxn;
	for(int i=x;i<=2000001;i+=lowbit(i)){
		tr[i][ex]+=v;
	}
}
int get(int x,int ex){
	int ans=0;
	x+=maxn;
	while(x){
		ans+=tr[x][ex];
		x-=lowbit(x);
	}
	return ans;
}
string s;
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		cin>>s;
		if(s=="Add"){
			scanf("%d%d%d",&x,&y,&z);
			if(x==0){
				if(y>z){
					mu++;
					sit[++cnt]=1<<30;
				}else{
					sit[++cnt]=-(1<<30);
				}
			}else{
				if(x>0){
					int key=(floor)((z*1.-y)/x);
					ke[++cnt]=key;
					sit[cnt]=1;
					if(key>1000000){
						sit[cnt]=-(1<<30);
					}
					else if(key<-1000000){
						mu++;
						sit[cnt]=1<<30;
					} else{
						add(key,1,sit[cnt]);
					}
				}else{
					int key=(ceil)((z*1.-y)/x);
					ke[++cnt]=key;
					if(key<-1000000){
						sit[cnt]=-(1<<30);
					}
					else if(key>1000000){
						mu++;
						sit[cnt]=1<<30;
					} else{
						add(key,1,sit[cnt]);
					}
				}
			}
		}
		if(s=="Del"){
			scanf("%d",&x);
			if(!vis[x]){
				vis[x]=1;
				if(sit[x]==(1<<30)){
					mu--;
				}else{
					if(sit[x]!=-(1<<30)){
						add(ke[x],-1,sit[x]);
					}
				}	
			}
		}
		if(s=="Query"){
			scanf("%d",&x);
			cout<<get(1000000,0)-get(x,0)+get(x-1,1)+mu<<endl;
		}
	}
	return 0;
}
posted @ 2021-07-28 20:41  Simex  阅读(41)  评论(0编辑  收藏  举报