poj 3580 splay

来源:互联网 发布:新西兰旅游 知乎 编辑:程序博客网 时间:2024/06/07 17:53

这题没啥好说的。。。就是splay裸题。。然而我的splay的常数大得要死。弄了好久才过了。。。。

注意打标记的写法能有效减少常数。

然后还是数组流好了。。。妈蛋开结构体太蛋疼了。。。。不过结构体合并答案的时候是可以带来方便的,因此我们对于贮存答案的数组还是弄个结构体比较好,比如该死的最大连续子段和。。。。

代码:

#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<algorithm>#include<string>#define rep(i_,a,b) for(int i_=(a);i_<=(b);i_++)using namespace std;const int maxn=201200;const int inf=2147483647;int fa[maxn],c[maxn][2],siz[maxn],ans[maxn],mins[maxn],mark[maxn],key[maxn],sta[maxn];bool rev[maxn];int n,m,root,tot;inline void release(int x){    if (x==0) return;    if (rev[x]){        swap(c[x][0],c[x][1]);        if (c[x][0]) rev[c[x][0]]=!rev[c[x][0]];        if (c[x][1]) rev[c[x][1]]=!rev[c[x][1]];        rev[x]=false;    }    if (mark[x]!=0){            if (c[x][0]) {                    mark[c[x][0]]+=mark[x];                    key[c[x][0]]+=mark[x];                    mins[c[x][0]]+=mark[x];            }            if (c[x][1]) {                    mark[c[x][1]]+=mark[x];                    key[c[x][1]]+=mark[x];                    mins[c[x][1]]+=mark[x];            }            mark[x]=0;    }}inline void updata(int x){    if (x==0) return;    release(x);    siz[x]=siz[c[x][0]]+siz[c[x][1]]+1;    mins[x]=key[x];    if (c[x][0]) mins[x]=min(mins[x],mins[c[x][0]]);    if (c[x][1]) mins[x]=min(mins[x],mins[c[x][1]]);}void link(int x,int y,int der){    if (x!=0) c[x][der]=y;    if (y!=0) fa[y]=x;    updata(x);}void cut(int x,int y,int der){    updata(x);    if (x!=0) c[x][der]=0;    if (y!=0) fa[y]=0;    updata(x);}inline void rorate(int x){    if (fa[x]==0) return ;    release(fa[x]);    release(x);    int t=fa[x],t1=fa[fa[x]];    int p=(c[t][1]==x);    int p1=(c[fa[t]][1]==t);    link(t1,x,p1);    link(t,c[x][!p],p);    link(x,t,!p);    updata(t);}inline void splay(int x,int y){    while (fa[x]!=y){      rorate(x);    }    updata(x);    if (y==0) root=x; else updata(y);}int getrank(int x,int k){    int i=x;    int j=k;    while (true){        release(i);        if (j==siz[c[i][0]]+1) return i;        if (siz[c[i][0]]+1<j) {            j-=(siz[c[i][0]]+1);            i=c[i][1];        } else{            i=c[i][0];        }    }}inline void getlr(int l,int r){     int lx=getrank(root,l);int rx=getrank(root,r);     splay(lx,0);     splay(rx,lx);}int  bt(int ff,int l,int r){    if (l>r) return 0;    if (l==r){        siz[l]=1;        fa[l]=ff;        updata(l);        return l;    }    int mid=(l+r)/2;    fa[mid]=ff;    c[mid][0]=bt(mid,l,mid-1);    c[mid][1]=bt(mid,mid+1,r);    updata(mid);    return mid;}string str;char ss[10];int main(){       scanf("%d",&n);    memset(rev,0,sizeof(rev));    rep(i,1,n){        scanf("%d",&key[i+1]);    }    key[1]=inf;    key[n+2]=inf;    tot=n+2;    root=bt(0,1,n+2);    scanf("%d",&m);    while (m--)    {      scanf("%s",ss);      str=string(ss);      if ( str == "ADD" ) {int l , r , d; scanf( "%d%d%d" , &l , &r , &d );getlr(l,r+2);            int t=c[c[root][1]][0];            mark[t]+=d;            key[t]+=d;            mins[t]+=d;}if ( str == "REVERSE" ) {int l , r; scanf( "%d%d" , &l , &r );            getlr(l,r+2);            int t=c[c[root][1]][0];            rev[t]=!rev[t];}if ( str == "REVOLVE" ) {int l , r , k; scanf( "%d%d%d" , &l , &r , &k );int w=r-l+1;k=((k%w)+w)%w;if (k==0)continue;getlr(r-k+1,r+2);int t=c[c[root][1]][0];cut(c[root][1],t,0);            getlr(l,l+1);            link(c[root][1],t,0);}if ( str == "INSERT" ) {    int x,p;scanf("%d%d",&x,&p);             getlr(x+1,x+2);             tot++;             key[tot]=p;             mins[tot]=p;             siz[tot]=1;             int t=c[root][1];             link(t,tot,0);}if ( str == "DELETE" ) {            int x,t;            scanf("%d",&x);            getlr(x,x+2);            t=c[root][1];            c[t][0]=0;            updata(t);            updata(root);}if ( str == "MIN" ) {            int l,r;scanf("%d%d",&l,&r);            getlr(l,r+2);            int t=c[c[root][1]][0];            updata(t);            printf("%d\n",mins[t]);}    }}





0 0
原创粉丝点击