【CQBZOJ 2856】[线段树]原子核研究

来源:互联网 发布:疯狂java讲义第5版 编辑:程序博客网 时间:2024/04/28 17:57

题目描述

线段树水题专项赛:Portal
要求一种数据结构使得能够支持插入一个值,删除一个值,查询最小的差值。(所有输入数据小于100000,并且你需要自动去重)

题目解析

一看,这不一思博线段树吗?维护每一个区间左右有多少空格,中间(不包含左右端点)的最短区间,然后两两合并就行了啊。
于是迅速码完代码,信心满满的交了,然后就爆成了0分。
考完检查,mdzz,数组没清零,mdzz,build的区间用的(1,n)。
我天,以后一定要记住,多组数据一定记得清零,线段树先找好区间,不要手残乱打。

代码

#include<iostream>#include<cstring>#include<cstdio>#include<set>#include<algorithm>using namespace std;#define MAXN 100000#define MAXM 100000#define INF 0x3f3f3f3ftypedef long long int LL;template<class T>void Read(T &x){    x=0;char c=getchar();bool flag=0;    while(c<'0'||'9'<c){if(c=='-')flag=1;c=getchar();}    while('0'<=c&&c<='9'){x=x*10+c-'0';c=getchar();}    if(flag)x=-x;}int L[MAXM*3],R[MAXM*3];int len[MAXM*3];int lval[MAXM*3],rval[MAXM*3],minval[MAXM*3];int sz;void updata(int x){    lval[x]=lval[x<<1];    if(lval[x<<1]==len[x<<1])lval[x]+=lval[x<<1|1];    rval[x]=rval[x<<1|1];    if(rval[x<<1|1]==len[x<<1|1])rval[x]+=rval[x<<1];    minval[x]=min(minval[x<<1],minval[x<<1|1]);    if(rval[x<<1]!=len[x<<1]&&lval[x<<1|1]!=len[x<<1|1])        minval[x]=min(minval[x],rval[x<<1]+lval[x<<1|1]);}void build(int l,int r,int x){    L[x]=l,R[x]=r;    len[x]=r-l+1;    lval[x]=rval[x]=len[x];    minval[x]=INF;    if(L[x]==R[x])return;    int mid=(l+r)>>1;    build(l,mid,x<<1);    build(mid+1,r,x<<1|1);    updata(x);}void insert(int pos,int x){    if(L[x]==R[x]){        lval[x]=rval[x]=0;        minval[x]=INF;        return;    }    int mid=(L[x]+R[x])>>1;    if(pos<=mid)insert(pos,x<<1);    else insert(pos,x<<1|1);    updata(x);}void del(int pos,int x){    if(L[x]==R[x]){        lval[x]=rval[x]=1;        minval[x]=INF;        return;    }    int mid=(L[x]+R[x])>>1;    if(pos<=mid)del(pos,x<<1);    else del(pos,x<<1|1);    updata(x);}int query(){    if(sz<2)return -1;    else return minval[1]+1;}bool has[MAXM+10];int main(){    //freopen("data2.in","r",stdin);    //freopen("atomic.out","w",stdout);    int T,n;    Read(T);    while(T--){        Read(n);        sz=0;        build(1,MAXM,1);        memset(has,0,sizeof(has));        char str[10];        int x;        for(int i=1;i<=n;++i){            scanf("%s",str);            if(str[0]=='g'){                Read(x);                if(!has[x]){                    has[x]=1,++sz;                    insert(x,1);                }            }            else if(str[0]=='r'){                Read(x);                if(has[x]){                    has[x]=0,--sz;                    del(x,1);                }            }            else                printf("%d\n",query());        }        putchar('\n');    }}
1 0