神秘物质

来源:互联网 发布:怎么打理淘宝店铺 编辑:程序博客网 时间:2024/03/29 07:14

题目大意

维护一个序列,支持单点删除和添加,以及查询区间内大于1的所有子区间的极差的最大值和最小值。

splay裸题

所有子区间极差的最大值=区间最大值-区间最小值
极差的最小值,容易发现一定是长度为2的区间
设新序列b[i]=abs(a[i]-a[i+1])维护b的区间最小值即可

要注意添加和删除时,更新前一项的b值

代码

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define fo(i,a,b)for(i=a;i<=b;i++)#define fod(i,a,b)for(i=a;i>=b;i--)#define ll long longusing namespace std;const int maxn=3e5+5;int a[maxn],root,cnt,mi[maxn],q[maxn],mx[maxn],fa[maxn],s[maxn],tree[maxn][2];int mxi[maxn],b[maxn],n,m,i,j;int read(){    int n=0;char c=getchar();    while ((c<'0')||(c>'9')) c=getchar();    while ((c>='0')&&(c<='9')) n=n*10+c-'0',c=getchar();    return n;}void update(int x){    mi[x]=min(a[x],min(mi[tree[x][0]],mi[tree[x][1]]));    mx[x]=max(a[x],max(mx[tree[x][0]],mx[tree[x][1]]));    mxi[x]=min(b[x],min(mxi[tree[x][0]],mxi[tree[x][1]]));    s[x]=s[tree[x][0]]+s[tree[x][1]]+1;}int pd(int x){return (tree[fa[x]][0]==x)?0:1;}void rotate(int x){    int y=fa[x],z=pd(x),z1=pd(y);    if (tree[y][z]=tree[x][1-z]) fa[tree[y][z]]=y;    if (fa[x]=fa[y]) tree[fa[x]][z1]=x;    tree[x][1-z]=y,fa[y]=x;    update(y);}void splay(int x,int y){    while(fa[x]!=y){        int f=fa[x];        if (fa[f]!=y) (pd(f)==pd(x))?rotate(f):rotate(x);        rotate(x);    }    update(x);    if (!y) root=x;}int kth(int x,int k){    if (s[tree[x][0]]+1==k) return x;    if (s[tree[x][0]]+1>k) return kth(tree[x][0],k);else    return kth(tree[x][1],k-s[tree[x][0]]-1);}void ins(int x,int y){    int w=kth(root,x),b1=kth(root,x+1);    splay(w,0);    b[w]=abs(a[w]-y);    if (b1==0){        tree[w][1]=++cnt,fa[cnt]=w;        mi[cnt]=mx[cnt]=a[cnt]=y,s[cnt]=1;        update(w);        return;    }    splay(b1,w);    tree[b1][0]=++cnt,fa[cnt]=b1;    mi[cnt]=mx[cnt]=a[cnt]=y,mxi[cnt]=b[cnt]=abs(y-a[b1]);    s[cnt]=1;    update(b1);update(w);}void del(int x){    int w=kth(root,x-1),b1=kth(root,x+1);    splay(w,0);    if (b1==0){        tree[w][1]=0,update(w);        return;    }    splay(b1,w);    b[w]=abs(a[w]-a[b1]);    tree[b1][0]=0;    update(b1);update(w);}char get(){    char c=getchar();    while ((c<'a')||(c>'z')) c=getchar();    c=getchar();    return c;}int main(){    mxi[0]=mi[0]=1e9;    cnt=n=read(),m=read();    fo(i,1,n) a[i]=read();    fo(i,1,n){        b[i]=abs(a[i]-a[i+1]);        if (i>1) fa[i-1]=i,tree[i][0]=i-1;        update(i);    }root=n;    while (m--){        char c=get();        int x=read(),y=read();        if (c=='e'){            del(x+1);            if (x!=1){                del(x),ins(x-1,y);                continue;            }            a[root]=y,b[root]=abs(y-a[tree[root][1]]);            update(root);        }        if (c=='n') ins(x,y);        if (c=='a'){            x=kth(root,x),y=kth(root,y);            splay(x,0),splay(y,x);            int s1,s2;            if(a[x]>a[y]) s1=a[x],s2=a[y];else s1=a[y],s2=a[x];            s1=max(mx[tree[y][0]],s1);              s2=min(mi[tree[y][0]],s2);            printf("%d\n",s1-s2);        }        if (c=='i'){            x=kth(root,x),y=kth(root,y);            splay(x,0),splay(y,x);            printf("%d\n",min(b[x],mxi[tree[y][0]]));        }    }}
0 0
原创粉丝点击