luogu P5482 [JLOI2011]不等式组

题面传送门
其实这道题是一眼秒了的。
因为\(A\)有正负所以显然按\(A\)正负开两颗平衡树维护即可。
但是并没有这么简单。
首先\(A=0\),这个要特判。
然后它还会重复撤销一个不等式多次所以也要特判。
大概没了。时间复杂度\(O(nlogn)\)
code:

#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define ll long long
#define db double
#define N 100000
#define M 30
#define mod 1000000007
#define eps (1e-7)
#define U unsigned int
#define IT set<ques>::iterator
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x))
using namespace std;
int n,m,A[N+5],B[N+5],C[N+5],op,x,y,z,cnt,fl[N+5],ans;char s[10];
struct FHQ_Treap{
	int l[N+5],r[N+5],key[N+5],siz[N+5],root1,root2,root3,root,cnt,now;db val[N+5];
	I int newnode(db x){key[++cnt]=rand();val[cnt]=x;siz[cnt]=1;return cnt;}
	I void up(int x){siz[x]=siz[l[x]]+siz[r[x]]+1;}
	I void split(db x,int now,int &a,int &b){
		if(!now) return (void)(a=b=0);
		x>=val[now]?(a=now,split(x,r[now],r[now],b)):(b=now,split(x,l[now],a,l[now])); up(now);
	} 
	I int merge(int x,int y){
		if(!x||!y) return x|y;return key[x]<key[y]?(r[x]=merge(r[x],y),up(x),x):(l[y]=merge(x,l[y]),up(y),y);
	}
	I void insert(db x){split(x,root,root1,root2);root=merge(root1,merge(newnode(x),root2));}
	I int find(db x,db y){split(x+eps,root,root1,root2);split(y-eps,root2,root2,root3);now=siz[root2];return root=merge(merge(root1,root2),root3),now;}
	I void erase(db x){split(x-eps,root,root1,root2);split(x,root2,root2,root3);root=merge(merge(root1,l[root2]),merge(r[root2],root3));}
}F1,F2;
int main(){
	freopen("1.in","r",stdin);freopen("1.out","w",stdout);
	srand(51569);re int i;scanf("%d",&n);for(i=1;i<=n;i++){
		scanf("%s",s+1);if(s[1]=='A'){
			cnt++;scanf("%d%d%d",&A[cnt],&B[cnt],&C[cnt]);if(!A[cnt]) ans+=B[cnt]>C[cnt];
			else A[cnt]>0?F1.insert((C[cnt]-B[cnt])*1.0/A[cnt]):F2.insert((C[cnt]-B[cnt])*1.0/A[cnt]);
		} 
		else if(s[1]=='D'){
			scanf("%d",&z);if(fl[z]) continue;if(!A[z]) ans-=B[z]>C[z];
			else A[z]>0?F1.erase((C[z]-B[z])*1.0/A[z]):F2.erase((C[z]-B[z])*1.0/A[z]);fl[z]=1;
		} 
		else scanf("%d",&x),printf("%d\n",F1.find(-1e9,x)+F2.find(x,1e9)+ans);
	}
}
上一篇:点分数


下一篇:[BZOJ4399]魔法少女LJJ----------线段树进阶