您的位置:首页 > 其它

bzoj2762 不等式组 树状数组

2016-02-01 17:29 381 查看
首先,题目中的a,b,c∈[-10^8,10^8]是没有意义的,因为询问的区间是[-10^6,10^6],所以就可以用树状数组做了。

具体地,对于不等式ax+b>c,从a>0,a<0,a=0三方面讨论,得出x的取值范围(>=或<=一个整数或无解或全体实数),然后对应的到整数区间上,例如:

1.x>=a(a为整数,这里的a不同于上面的a),则区间[a,10^6]都+1

2.x无解,直接无视;

3.x为全体实数,则区间[-10^6,10^6]都+1。

注意c++的数组没有负的,因此区间的所有端点都要加上10^6+1使区间范围变成正数。

这样查询就转化为了单点的值,于是整个问题就转化为了区间修改单点查询的经典树状数组题目。注意:题目中的删除合法,但不保证不会删除已经删除了的,因此要开一个数组记录。

AC代码如下:

<span style="font-size:18px;">#include<iostream>
#include<cstdio>
#include<cmath>
#define n 2000001
using namespace std;

int c[2000005],x[100005],y[100005]; bool vis[100005];
int read(){
int x=0,f=1; char ch=getchar();
while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
if (ch=='-'){ f=-1; ch=getchar(); }
while (ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }
return x*f;
}
void add(int u,int t){
for (; u<=n; u+=u&(-u)) c[u]+=t;
}
void mdy(int u,int v,int t){
if (u>v) return; u=max(u,1); v=min(v,n);
add(u,t); add(v+1,-t);
}
int getsum(int u){
int sum=0; for (; u; u-=u&(-u)) sum+=c[u]; return sum;
}
int main(){
int cas,i=0; scanf("%d",&cas);
while (cas--){
char ch=getchar(); while (ch<'A' || ch>'Z') ch=getchar();
if (ch=='A'){
int u=read(),v=read(),w=read(); i++;
if (u<0){ x[i]=1; y[i]=ceil((double)(w-v)/u)+1000000; } else
if (u>0){ x[i]=floor((double)(w-v)/u)+1000002; y[i]=n; } else
if (v>w){ x[i]=1; y[i]=n; } else{ x[i]=2; y[i]=1; }
mdy(x[i],y[i],1);
} else if (ch=='D'){
int k=read(); if (vis[k]) continue;
vis[k]=1; mdy(x[k],y[k],-1);
} else printf("%d\n",getsum(read()+1000001));
}
return 0;
}
</span>

lych
2016.2.1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: