首页 > 程序开发 > 综合编程 > 其他综合 >

BZOJ 1895题目解答

2017-04-12

BZOJ 1895题目解答:Splay模板题,我WA了一次,TLE了两次,总结一下犯的错误就是两个。

BZOJ 1895题目解答:Splay模板题,我WA了一次,TLE了两次,总结一下犯的错误就是两个。

pushup里默认把mn[x]设为inf而非v[x] 数组开小,只开了1e5,应该至少开2e5的
/*
User:Small
Language:C++
Problem No.:1895
*/
#include
#define ll long long
#define inf 999999999
using namespace std;
const int M=3e5+5;
int n,m,a[M],rt,cnt,id[M],ch[M][2],fa[M],mn[M],v[M],siz[M],lazy[M];
bool tag[M];
queue q;
void pushup(int x){
    int lson=ch[x][0],rson=ch[x][1];
    siz[x]=1;
    mn[x]=v[x];
    if(lson){
        siz[x]+=siz[lson];
        mn[x]=min(mn[x],mn[lson]);
    }
    if(rson){
        siz[x]+=siz[rson];
        mn[x]=min(mn[x],mn[rson]);
    }
}
void pushdown(int x){
    int &lson=ch[x][0],&rson=ch[x][1];
    if(lson){
        lazy[lson]+=lazy[x];
        mn[lson]+=lazy[x];
        v[lson]+=lazy[x];
    }
    if(rson){
        lazy[rson]+=lazy[x];
        mn[rson]+=lazy[x];
        v[rson]+=lazy[x];
    }
    lazy[x]=0;
    if(tag[x]){
        tag[lson]^=1;
        tag[rson]^=1;
        tag[x]^=1;
        swap(lson,rson);
    }
}
int get(int x){
    return ch[fa[x]][1]==x;
}
void rotate(int x,int &k){
    int y=fa[x],z=fa[y],side=get(x);
    if(y==k) k=x;
    else ch[z][ch[z][1]==y]=x;
    ch[y][side]=ch[x][side^1];
    fa[ch[y][side]]=y;
    fa[y]=x;
    ch[x][side^1]=y;
    fa[x]=z;
    pushup(y);
    pushup(x);
}
void splay(int x,int &k){
    while(x!=k){
        if(fa[x]!=k) rotate((get(x)==get(fa[x])?fa[x]:x),k);
        rotate(x,k);
    }
}
int findx(int x){
    int now=rt;
    while(1){
        if(tag[now]||lazy[now]) pushdown(now);
        if(siz[ch[now][0]]>=x) now=ch[now][0];
        else{
            x-=siz[ch[now][0]]+1;
            if(x<=0) return now;
            now=ch[now][1];
        }
    }
}
int spilt(int l,int r){
    int x=findx(l),y=findx(r+2);
    splay(x,rt);splay(y,ch[x][1]);
    return y;
}
void build(int l,int r,int f){
    if(l>r) return;
    int mid=l+r>>1,now=id[mid],last=id[f];
    v[now]=a[mid];
    if(l==r){
        siz[now]=1;
        mn[now]=a[mid];
    }
    else{
        build(l,mid-1,mid);
        build(mid+1,r,mid);
        pushup(now);
    }
    fa[now]=last;
    ch[last][mid>f]=now;
}
void add(int l,int r,int k){
    int x=spilt(l,r),y=ch[x][0];
    lazy[y]+=k;
    mn[y]+=k;
    v[y]+=k;
    pushup(x);
    pushup(fa[x]);
}
void ins(int x,int p){
    int y=spilt(x+1,x);
    if(!q.empty()){
        id[1]=q.front();
        q.pop();
    }
    else id[1]=++cnt;
    siz[id[1]]=1;
    v[id[1]]=mn[id[1]]=p;
    fa[id[1]]=y;
    ch[y][0]=id[1];
    pushup(y);
    pushup(fa[y]);
}
void del(int x){
    int y=spilt(x,x),z=ch[y][0];
    siz[z]=lazy[z]=tag[z]=v[z]=mn[z]=ch[z][0]=ch[z][1]=fa[z]=0;
    q.push(z);
    ch[y][0]=0;
    pushup(y);
    pushup(fa[y]);
}
int getmin(int l,int r){
    int y=spilt(l,r);
    return mn[ch[y][0]];
}
void rev(int l,int r){
    int y=spilt(l,r);
    tag[ch[y][0]]^=1;
}
void revo(int l,int r,int t){
    t%=(r-l+1);
    if(t==0) return;
    int y=spilt(r-t+1,r),x=ch[y][0];
    fa[x]=ch[y][0]=0;
    pushup(y);
    pushup(fa[y]);
    y=spilt(l,l-1);
    ch[y][0]=x;
    fa[x]=y;
    pushup(y);
    pushup(fa[y]);
}
int main(){
    freopen("data.in","r",stdin);//
    scanf("%d",&n);
    a[1]=a[n+2]=inf;
    for(int i=2;i<=n+1;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=n+2;i++) id[i]=i;
    rt=(n+3)>>1,cnt=n+2;
    build(1,n+2,0);
    scanf("%d",&m);
    while(m--){
        char op[15];
        int x,y,p;
        scanf("%s%d",op,&x);
        switch(op[0]){
            case &#39;D&#39;:n--;del(x);break;
            case &#39;I&#39;:{
                scanf("%d",&p);
                n++;
                ins(x,p);
                break;
            }
            case &#39;A&#39;:{
                scanf("%d%d",&y,&p);
                if(x>y) swap(x,y);
                add(x,y,p);
                break;
            }
            case &#39;M&#39;:{
                scanf("%d",&y);
                printf("%d\n",getmin(x,y));
                break;
            }
            case &#39;R&#39;:{
                if(op[3]==&#39;E&#39;){
                    scanf("%d",&y);
                    if(x==y) continue;
                    if(x>y) swap(x,y);
                    rev(x,y);
                }
                else{
                    scanf("%d%d",&y,&p);
                    if(x>y) swap(x,y);
                    revo(x,y,p);
                }
                break;
            }
        }
    }
    return 0;
}
相关文章
最新文章
热点推荐