jzoj 4986. 【GDOI2017模拟2.25】神秘物质 可持久化treap

来源:互联网 发布:dota2淘宝买饰品安全吗 编辑:程序博客网 时间:2024/05/17 04:06

题意

给一个序列,要求资瓷如下操作:
merge x e将第x个和第x+1个元素合并为元素e
insert x e在第x个和第x+1个元素之间插入元素e
max l r查询区间[l,r]之间的极差,也就是最大值减最小值
min l r查询区间[l,r]的子区间的最小极差
n,m<=100000

分析

第一次打可持久化treap,调了一个下午终于调出来了。。。
主要就是merge和split操作,其余注意一下细节即可。
每个元素维护最大值最小值和相邻两个元素的差的最小值即可。
感觉treap代码比splay代码优美多了。
序列操作?splay?我会treap!

代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<ctime>#define N 100005#define inf 0x7fffffffusing namespace std;typedef pair<int,int> P;int n,m,cnt,a[N],root;struct treap{int l,r,val,key1,key2,mn,mx,fix,size;}t[N*2];int read(){    int x=0,f=1;char ch=getchar();    while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}int newnode(int key1,int key2){    cnt++;    t[cnt].key1=t[cnt].mn=t[cnt].mx=key1;t[cnt].key2=t[cnt].val=key2;t[cnt].fix=rand();t[cnt].size=1;    return cnt;}int updata(int d){    t[d].mn=min(t[d].key1,min(t[t[d].l].mn,t[t[d].r].mn));    t[d].mx=max(t[d].key1,max(t[t[d].l].mx,t[t[d].r].mx));    t[d].val=min(t[d].key2,min(t[t[d].l].val,t[t[d].r].val));    t[d].size=t[t[d].l].size+t[t[d].r].size+1;}int merge(int x,int y){    if (!x||!y) return x+y;    if (t[x].fix<t[y].fix)    {        t[x].r=merge(t[x].r,y);        updata(x);        return x;    }    else    {        t[y].l=merge(x,t[y].l);        updata(y);        return y;    }}P split(int x,int k){    if (k<=0||!x) return P(0,x);    if (k<=t[t[x].l].size)    {        P f=split(t[x].l,k);        t[x].l=f.second;        updata(x);        return P(f.first,x);    }    else    {        P f=split(t[x].r,k-t[t[x].l].size-1);        t[x].r=f.first;        updata(x);        return P(x,f.second);    }}void ins(int key1,int key2){    int x=newnode(key1,key2);    root=merge(root,x);}int main(){    srand((unsigned)time(NULL));    n=read();m=read();    t[0].mn=t[0].val=inf;    for (int i=1;i<=n;i++) a[i]=read();    for (int i=1;i<=n;i++) ins(a[i],abs(a[i+1]-a[i]));    for (int i=1;i<=m;i++)    {        char ch[5];        scanf("%s",ch);        int l=read(),r=read();        if (ch[1]=='a')        {            P x=split(root,l-1),y=split(x.second,r-l+1);            printf("%d\n",t[y.first].mx-t[y.first].mn);            root=merge(merge(x.first,y.first),y.second);        }        else if (ch[1]=='i')        {            P x=split(root,l-1),y=split(x.second,r-l);            printf("%d\n",t[y.first].val);            root=merge(merge(x.first,y.first),y.second);        }        else if (ch[1]=='e')        {            if (l==1)            {                P x=split(root,1),y=split(x.second,1),z=split(y.second,1);                t[y.first].key1=t[y.first].mn=t[y.first].mx=r;t[y.first].key2=t[y.first].val=abs(r-t[z.first].key1);                root=merge(merge(y.first,z.first),z.second);            }            else            {                P x=split(root,l-2),y=split(x.second,1),z=split(y.second,1),u=split(z.second,1),v=split(u.second,1);                t[y.first].key2=t[y.first].val=abs(t[y.first].key1-r);t[z.first].key1=t[z.first].mn=t[z.first].mx=r;t[z.first].key2=t[z.first].val=abs(t[v.first].key1-r);                root=merge(merge(merge(merge(x.first,y.first),z.first),v.first),v.second);            }        }        else        {            P x=split(root,l-1),y=split(x.second,1),z=split(y.second,1);            int w=newnode(r,abs(r-t[z.first].key1));t[y.first].key2=t[y.first].val=abs(r-t[y.first].key1);            root=merge(merge(merge(merge(x.first,y.first),w),z.first),z.second);        }    }    return 0;}
0 0
原创粉丝点击