BZOJ2762: [JLOI2011]不等式组
n<=100000个操作:添加一个不等式ax+b>c,删除一个不等式,查询当x=k时有多少不等式组满足要求,abs(k)<=1e6。
按a的正负来分情况,然后树状数组维护即可。
a=0:b>c就全部+1否则不理,注意不要忘了把他扔进数组里!!!!!
a>0:x>(c-b)/a,把它向上取整,并且在-1e6,1e6范围内加一,这么写:min((int)max(floor((double)(z-y)/x+1),-fix+1.0),fix)+fix,fix=1e6+一点
a<0:x<(c-b)/a,把它向下取整,并且在-1e6,1e6范围内加一,这么写:min((int)max(ceil((double)(z-y)/x-1),-fix+1.0),fix)+fix,之所以后面要多加个fix是因为树状数组下标要正数
因为忘了把a=0时的情况扔进记不等式的数组里而WA了3次。。。。。。
很好。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 //#include<assert.h> 5 #include<math.h> 6 #include<algorithm> 7 //#include<iostream> 8 using namespace std; 9 10 int n; 11 #define maxn 100011 12 #define maxm 2000011 13 const int fix=1e6+3; 14 struct BIT 15 { 16 int a[maxm],n; 17 BIT() {memset(a,0,sizeof(a));n=fix*2;} 18 void add(int x,int v) {for (;x<=n;x+=x&-x) a[x]+=v;} 19 int query(int x) {int ans=0;for (;x;x-=x&-x) ans+=a[x];return ans;} 20 }t; 21 int line[maxn],li=0;bool vis[maxn];int ty[maxn]; 22 int x,y,z;char s[11]; 23 const double eps=1e-9; 24 int main() 25 { 26 scanf("%d",&n); 27 while (n--) 28 { 29 scanf("%s",s); 30 if (s[0]=='A') 31 { 32 li++;vis[li]=0; 33 scanf("%d%d%d",&x,&y,&z); 34 if (x==0) 35 { 36 if (y>z) t.add(1,1),line[li]=1;else{line[li]=2;} 37 ty[li]=-1; 38 } 39 else 40 { 41 if (x>0) line[li]=min((int)max(floor((double)(z-y)/x+1),-fix+1.0),fix)+fix, 42 t.add(line[li],1),ty[li]=1; 43 else line[li]=min((int)max(ceil((double)(z-y)/x-1),-fix+1.0),fix)+fix, 44 t.add(1,1),t.add(line[li]+1,-1),ty[li]=0; 45 } 46 // assert(line[li]>=1 && line[li]<=t.n); 47 } 48 else if (s[0]=='D') 49 { 50 scanf("%d",&x); 51 if (!vis[x]) 52 { 53 vis[x]=1; 54 if (ty[x]==1) t.add(line[x],-1); 55 else if (ty[x]==0) t.add(1,-1),t.add(line[x]+1,1); 56 else if (ty[x]==-1) 57 if (line[x]==1) t.add(1,-1); 58 } 59 } 60 else if (s[0]=='Q') 61 { 62 scanf("%d",&x); 63 // if (x+fix>t.n) {printf("QAQ%d",x);assert(0);} 64 printf("%d\n",t.query(x+fix)); 65 } 66 } 67 return 0; 68 }