Loading

P5482 [JLOI2011]不等式组

题面

维护多个形如 \(ax + b> c\) 的不等式,支持下面操作,操作 \(n\)

  • Add a b c:表明要往不等式组添加一条不等式 \(ax+b>c\)
  • Del i:代表删除第 i 条添加的不等式(最先添加的是第 1 条)。
  • Query k:代表一个询问,即当 \(x=k\) 时,在当前不等式组内成立的不等式的数量。

\(1 \leq n \leq 10^5, a,b,c\in[-10^8 , 10^8], k \in [-10^6, 10^6]\)

solution

将不等式变一下形,对 \(a\) 进行分类讨论

  • \(a = 0\)

不等式变为 \(b > c\),此时不等式与 \(x\) 无关,如果此时的 \(b > c\) 则不等式恒成立,sp++,否则不等式永远都不成立

  • \(a > 0\)

不等式变为 \(x > \frac{c- b}{a}\) ,因为 \(k \in [-10^6, 10^6]\), 如果此时 \(\frac{c- b}{a} > 10^6\) 不等式恒不成立,如果 \(\frac{c- b}{a} < -10^6\) 不等式恒成立,sp++,如果 \(-10^6<\frac{c- b}{a} < 10^6\) ,把 \(\frac{c- b}{a}\) 加到一个树状数组中

  • \(a < 0\)

和上面一个样,就是不等式变一下号就好了,如果在范围之内,就把 \(\frac{c- b}{a}\) 加到另一个树状数组中

最后答案就是 \(sp + sum1[1 - k] + sum2[k, 1e6]\)

后面那两项树状数组前缀和就能搞定了

/*
work by:Ariel
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define ll long long
using namespace std;
const int N = 1e6 + 1;;
int read() {
  int x = 0, f = 1; char c = getchar();
  while(c < '0' || c > '9') {if(c == '-')  f = -1;c = getchar();}
  while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
  return x * f;
}
int n, c1[N << 1], c2[N << 1], ty[N], sp, tx[N], tot, tz[N];
char s[N];
void Insert(int x, int k, int c[]) {
   x += N;
   for (int i = x; i <= 2000001; i += i & (-i)) c[i] += k;
}
int Query(int x, int c[]) {
   x += N;
   int ans = 0;
   for (int i = x; i; i -= i & (-i)) ans += c[i];
   return ans;
}
int main() {
  n = read();
  for (int i = 1; i <= n; i++) {
  	scanf("%s", s + 1);
  	if (s[1] == 'A') {
  	   int a = read(), b = read(), c = read();
	   if (a == 0) {
          if (b > c) {
	   	     sp++, ty[++tot] = (1 << 30);
	       } 
	       else ty[++tot] = -(1 << 30);	   	
	     }
	   else if(a < 0) {// x < (c - b) / a 
	   	  tx[++tot] = (ceil)((c * 1.0 - b) / a), ty[tot] = 2;
	   	  if (tx[tot] > 1e6) sp++, ty[tot] = (1 << 30);	 
		  else if(tx[tot] < -1e6) ty[tot] = -(1 << 30);
		  else Insert(tx[tot], 1, c2);
	   }
	   else {
	   	 tx[++tot] = (floor)((c * 1.0 - b) / a), ty[tot] = 1;//// x > (c - b) / a
	   	 if (tx[tot] > 1e6) ty[tot] = -(1 << 30);
	   	 else if(tx[tot] < -1e6) ty[tot] = (1 << 30), sp++;
	   	 else Insert(tx[tot], 1, c1);
	   }
	 }
	else if (s[1] == 'D') {
	  int x = read();
	  if (tz[x]) continue;
	  tz[x] = 1;
	  if (ty[x] == (1 << 30)) sp--;
	  else if(ty[x] == 1) Insert(tx[x], -1, c1);
	  else if(ty[x] == 2) Insert(tx[x], -1, c2);  
	}
	else {
	  int x = read();
	  printf("%d\n", sp + Query(x - 1, c1) + Query(1e6, c2) - Query(x, c2));
	}
  }
  return 0;
}
posted @ 2021-07-15 20:06  Dita  阅读(44)  评论(0编辑  收藏  举报