Splay总结

来源:互联网 发布:java所有关键字 编辑:程序博客网 时间:2024/05/16 00:54

写在前面

最近学Splay就好久没有在没有写过博客了,最近想做个总结。
基本思路中所有的树都满足左儿子<树根<右儿子。
题目的所有代码都放在可文章的最后

Bzoj 3224 普通平衡树

http://www.lydsy.com/JudgeOnline/problem.php?id=3224

按值建Splay。

Bzoj 3223 文艺平衡树

http://www.lydsy.com/JudgeOnline/problem.php?id=3223

注意下传标记就可以了。

Bzoj 1588 营业额统计

http://www.lydsy.com/JudgeOnline/problem.php?id=1588

不想写字,会做Bzoj 3224这个题应该没问题。

Bzoj 1269 文本编辑器

http://www.lydsy.com/JudgeOnline/problem.php?id=1269

把光标的前一个字符作为树的根,剩下就简单了。

Bzoj 1507 Editor

http://www.lydsy.com/JudgeOnline/problem.php?id=1507

同Bzoj 1269

Bzoj 1503 郁闷的出纳员

http://www.lydsy.com/JudgeOnline/problem.php?id=1503

扣工资相当于把所有员工工资加上k,每一次扣工资就把工资小于min 的部分删去,并累加答案。
注意如果某一员工的初始工资小于min,不用加入到树中,也不要累加答案。

Bzoj 1552 robotic sort

http://www.lydsy.com/JudgeOnline/problem.php?id=1552

令物品的编号为Ai100000+i 就可以解决编号相同的问题。记录下区间最小值。然后每一次顺着区间最小值去找就可以了。

Bzoj 1895 Supermemo

http://www.lydsy.com/JudgeOnline/problem.php?id=1895

revolve x y t,令t = t mod (r-l+1) 。如果t = 0,直接退出。
有两种思路:
一种是一次删除和一次插入。删除[1+y-k,y],再将[1+y-k,y]插入到x前面。
另一种是三次旋转。先后旋转[x,y] , [x,x+k-1] , [x+k,y]。

Bzoj 1500 维修数列

http://www.lydsy.com/JudgeOnline/problem.php?id=1500

注意开内存池就可以了,最大子序和为max{左子树最大子序和,右子树最大子序和,max{左子树右边最大子序和,0}+根节点元素+max{右子树左边最大子序和,0}}。

Bzoj 3224 代码

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = 100000+50;const int inf = 0x3f3f3f3f;int ch[Size][2],total[Size],data[Size],pre[Size],size[Size];int tot,root;void Read(int &);void NewNode(int &,int,int);void Splay(int,int);void Rotate(int,int);void Updata(int);void Insert(int);void Delete(int);int FindRank(int);int Order(int);int GetPre(int);int GetNxt(int);int main(){    int t,x,y;    NewNode(root,0,-inf);NewNode(ch[root][1],root,inf);    Read(t);    while( t-- ){        Read(x);Read(y);        if(x==1) Insert(y);        else if(x==2) Delete(y);        else if(x==3) printf("%d\n",FindRank(y));        else if(x==4) printf("%d\n",Order(y+1));        else if(x==5) printf("%d\n",data[GetPre(y-1)]);        else if(x==6) printf("%d\n",data[GetNxt(y+1)]);    }    return 0;}void Read(int &in){    char ch;int f=1;    for(ch=getchar();ch>'9'||ch<'0';ch=getchar()) if(ch=='-') f=-1;    for(in=0;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0';    in *= f;}void NewNode(int &r,int father,int key){    pre[r=++tot] = father;    size[r] = total[r] = 1;    data[r] = key;}void Splay(int r,int goal){    int x,y,kind;    while(pre[r] != goal)        if(pre[pre[r]]==goal) Rotate(r,ch[pre[r]][0]==r);        else {            x=pre[r];y=pre[x];kind=ch[y][1]==x;            if(ch[x][kind]==r) Rotate(x,!kind),Rotate(r,!kind);            else Rotate(r,kind),Rotate(r,!kind);        }    if(!goal) root=r;}void Rotate(int r,int way){    int t = pre[r];    pre[ch[t][!way]=ch[r][way]] = t;    if(pre[t]) ch[pre[t]][ch[pre[t]][1]==t] = r;    pre[r] = pre[t];    pre[ch[r][way]=t] = r;    Updata(t);Updata(r);}void Updata(int r){    if(!r) return ;    size[r] = size[ch[r][0]]+size[ch[r][1]]+total[r];}void Insert(int x){    Splay(GetPre(x-1),0);Splay(GetNxt(x+1),root);    if(ch[ch[root][1]][0]) ++total[ch[ch[root][1]][0]],++size[ch[ch[root][1]][0]];    else NewNode(ch[ch[root][1]][0],ch[root][1],x);    Updata(ch[root][1]);Updata(root);}void Delete(int x){    Splay(GetPre(x-1),0);Splay(GetNxt(x+1),root);    if(total[ch[ch[root][1]][0]]==1) ch[ch[root][1]][0]=0;    else --total[ch[ch[root][1]][0]],--size[ch[ch[root][1]][0]];    Updata(ch[root][1]);Updata(root);}int FindRank(int k){    int ans = 0;    int now = root;    while(data[now] != k)        if(data[now]<k) ans+=(size[ch[now][0]]+total[now]),now=ch[now][1];        else now=ch[now][0];    return ans+size[ch[now][0]];}int Order(int k){    int now = root;    while(true)        if(size[ch[now][0]]>=k) now=ch[now][0];        else if(size[ch[now][0]]+total[now]>=k) return data[now];        else k-=(size[ch[now][0]]+total[now]),now=ch[now][1];}int GetPre(int x){    int now = root;    while(data[now] != x)        if(data[now] > x)            if(!ch[now][0]) break;            else now=ch[now][0];        else            if(!ch[now][1]) break;            else now=ch[now][1];    while(data[now]>x) now=pre[now];    return now;}int GetNxt(int x){    int now = root;    while(data[now] != x)        if(data[now] > x)            if(!ch[now][0]) break;            else now=ch[now][0];        else            if(!ch[now][1]) break;            else now=ch[now][1];    while(data[now]<x) now=pre[now];    return now;}

Bzoj 3223 代码

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = 100000+50;int ch[Size][2],rev[Size],data[Size],pre[Size],size[Size];int root,total;void Read(int &);void NewNode(int &,int,int);void Build(int &,int,int,int);void Splay(int,int);void Rotate(int,int);int Order(int);void PushDown(int);void PushRev(int);void Updata(int);void Rev(int,int);void Display(int);int main(){    int n,m,x,y;    Read(n);Read(m);    NewNode(root,0,0);NewNode(ch[root][1],root,0);    Build(ch[ch[root][1]][0],1,n,ch[root][1]);    Updata(ch[root][1]);Updata(root);    for(int i=1;i<=m;++i){        Read(x);Read(y);        Rev(x,y);    }    Display(root);    return 0;}void Read(int &in){    char ch;    for(ch=getchar();ch>'9'||ch<'0';ch=getchar());    for(in=0;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0';}void NewNode(int &r,int father,int key){    pre[r=++total] = father;    data[r] = key;    size[r] = 1;}void Build(int &node,int l,int r,int father){    if(l > r) return;    int mid = (l+r)>>1;    NewNode(node,father,mid);    Build(ch[node][0],l,mid-1,node);    Build(ch[node][1],mid+1,r,node);    Updata(node);}void Splay(int r,int goal){    int x,y,kind;    while(pre[r] != goal)        if(pre[pre[r]]==goal) Rotate(r,ch[pre[r]][0]==r);        else{            x=pre[r];y=pre[x];kind=ch[y][1]==x;            if(ch[x][kind]==r) Rotate(x,!kind),Rotate(r,!kind);            else Rotate(r,kind),Rotate(r,!kind);        }    if(!goal) root = r;}void Rotate(int r,int way){    int t = pre[r];    pre[ch[t][!way]=ch[r][way]] = t;    if(pre[t]) ch[pre[t]][ch[pre[t]][1]==t] = r;    pre[r] = pre[t];    pre[ch[r][way]=t] = r;    Updata(t);Updata(r);Updata(pre[r]);}int Order(int k){    int now = root;    while(true){        PushDown(now);        if(size[ch[now][0]]>=k) now = ch[now][0];        else if(size[ch[now][0]]+1==k) return now;        else k-=(1+size[ch[now][0]]),now=ch[now][1];    }}void PushDown(int r){    if(!r) return ;    if(rev[r]){        PushRev(ch[r][0]);        PushRev(ch[r][1]);        rev[r] = 0;    }}void PushRev(int r){    if(!r) return ;    swap(ch[r][0],ch[r][1]);    rev[r] ^= 1;}void Updata(int r){    if(!r) return ;    size[r] = size[ch[r][0]]+size[ch[r][1]]+1;}void Rev(int l,int r){    Splay(Order(l),0);Splay(Order(r+2),root);    PushRev(ch[ch[root][1]][0]);}void Display(int r){    if(!r) return ;    PushDown(r);    Display(ch[r][0]);    if(data[r]) printf("%d ",data[r]);    Display(ch[r][1]);}

Bzoj 1588 代码

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = (1<<17)+1;const int inf = 0x3f3f3f3f;int ch[Size][2],data[Size],pre[Size],root,n,total;long long ans;void NewNode(int&,int,int);void Splay(int,int);void Rotate(int,int);int Get(int);int Pre(int);int Nxt(int);void Insert(int);int main(){    scanf("%d%lld",&n,&ans);    NewNode(root,0,ans);    for(int i=2,r,t;i<=n;++i){        scanf("%d",&r);        ans += (t=min(r-Pre(r),Nxt(r)-r));        if(t) Insert(r);    }    printf("%lld",ans);    return 0;}void NewNode(int &r,int father,int key){    pre[r=++total] = father;    data[r] = key;    ch[r][0] = ch[r][1] = 0;}void Splay(int r,int goal){    int x,y,kind;    while(pre[r] != goal)        if(pre[pre[r]]==goal) Rotate(r,ch[pre[r]][0]==r);        else{            x=pre[r];y=pre[x];kind=ch[y][1]==x;            if(ch[x][kind]==r) Rotate(x,!kind),Rotate(r,!kind);            else Rotate(r,kind),Rotate(r,!kind);        }    if(!goal) root=r;}void Rotate(int r,int way){    int tmp=pre[r];    pre[ch[tmp][!way]=ch[r][way]] = tmp;    if(pre[tmp]) ch[pre[tmp]][ch[pre[tmp]][1]==tmp] = r;    pre[r] = pre[tmp];    pre[ch[r][way]=tmp] = r;}int Get(int x){    int now=root;    while(true)        if(data[now]==x) break;        else if(data[now]>x)            if(ch[now][0]) now=ch[now][0];            else break;        else            if(ch[now][1]) now=ch[now][1];            else break;    return now;}int Pre(int x){    int now=Get(x);    while(data[now]>x && now) now=pre[now];    if(!now) return -inf;    Splay(now,0);    return data[root];}int Nxt(int x){    int now=Get(x);    while(data[now]<x && now) now=pre[now];    if(!now) return inf;    Splay(now,0);    return data[root];}void Insert(int x){    int now=root;    while(true)        if(data[now]>x)            if(ch[now][0]) now=ch[now][0];            else break;        else             if(ch[now][1]) now=ch[now][1];            else break;    NewNode(ch[now][data[now]<x],now,x);    Splay(ch[now][data[now]<x],0);}

Bzoj 1269 代码

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = (1<<21)+50;int ch[Size][2],pre[Size],size[Size],rev[Size];char data[Size],str[Size],type[20];int root,total;bool first;void NewNode(int &,int,char);void Build(int &,int,int,int);void Splay(int,int);void Rotate(int,int);void Updata(int);void PushDown(int);void PushRev(int);int Order(int);void Move(int);void Insert(int);void Delete(int);void Rev(int);void Get();void Prev();void Next();void Display(int);void Debug();int main(){    NewNode(root,0,' ');NewNode(ch[root][1],root,' ');    Updata(root);    int t,n;    scanf("%d",&t);    while( t-- ){        scanf("%s",type);        if(*type=='M') scanf("%d",&n),Move(n);        else if(*type=='I') scanf("%d",&n),Insert(n);        else if(*type=='D') scanf("%d",&n),Delete(n);        else if(*type=='R') scanf("%d",&n),Rev(n);        else if(*type=='G') Get();        else if(*type=='P') Prev();        else Next();    }    return 0;}void NewNode(int &r,int father,char g){    pre[r=++total] = father;    size[r] = 1;    data[r] = g;}void Build(int &node,int l,int r,int father){    if(l > r) return ;    int mid = (l+r)>>1;    NewNode(node,father,str[mid]);    Build(ch[node][0],l,mid-1,node);    Build(ch[node][1],mid+1,r,node);    Updata(node);}void Splay(int r,int goal){    int x,y,kind;    while(pre[r] != goal)        if(pre[pre[r]]==goal) Rotate(r,ch[pre[r]][0]==r);        else {            x=pre[r];y=pre[x];kind=ch[y][1]==x;            if(ch[x][kind]==r) Rotate(x,!kind),Rotate(r,!kind);            else Rotate(r,kind),Rotate(r,!kind);        }    if(!goal) root=r;}void Rotate(int r,int way){    int t = pre[r];    pre[ch[t][!way]=ch[r][way]] = t;    if(pre[t]) ch[pre[t]][ch[pre[t]][1]==t] = r;    pre[r] = pre[t];    pre[ch[r][way]=t] = r;    Updata(t);Updata(r);}void Updata(int r){    if(!r) return ;    size[r] = size[ch[r][0]]+size[ch[r][1]]+1;}void PushDown(int r){    if(rev[r]){        PushRev(ch[r][0]);        PushRev(ch[r][1]);        rev[r] = 0;    }}void PushRev(int r){    if(!r) return ;    swap(ch[r][0],ch[r][1]);    rev[r] ^= 1;}int Order(int k){    int now = root;    while(true){        PushDown(now);        if(size[ch[now][0]]>=k) now=ch[now][0];        else if(size[ch[now][0]]+1==k) return now;        else k-=(size[ch[now][0]]+1),now=ch[now][1];    }}void Move(int k){    Splay(Order(k+1),0);}void Insert(int k){    for(int i=0;i<k;++i){        str[i] = getchar();        if(str[i]>126 || str[i]<32) --i;    }    Splay(Order(size[ch[root][0]]+2),root);    Build(ch[ch[root][1]][0],0,k-1,ch[root][1]);    Updata(ch[root][1]);Updata(root);}void Delete(int k){    Splay(Order(size[ch[root][0]]+2+k),root);    ch[ch[root][1]][0] = 0;    Updata(ch[root][1]);Updata(root);}void Rev(int k){    Splay(Order(size[ch[root][0]]+2+k),root);    PushRev(ch[ch[root][1]][0]);}void Get(){    putchar(data[Order(size[ch[root][0]]+2)]);putchar(10);}void Prev(){    Splay(Order(size[ch[root][0]]),0);}void Next(){    Splay(Order(size[ch[root][0]]+2),0);}void Display(int r){    if(!r) return ;    PushDown(r);    Display(ch[r][0]);    putchar(data[r]);    Display(ch[r][1]);}void Debug(){    Display(root);putchar(10);}

Bzoj 1507 代码

#include <cstdio>#include <cstring>#include <algorithm>using std::swap;const int Size = (1<<21)+50;int ch[Size][2],root,total,pre[Size],size[Size];char c[Size],str[Size],type[20];void Init();void NewNode(int&,int,char);void Rotate(int,int);void Splay(int,int);void Build(int&,int,int,int);void Updata(int);int Order(int);void Display(int);void Move(int);void Insert(int);void Delete(int);void Get(int);void Prev();void Next();int main(){    int n,pos;    scanf("%d",&n);    Init();    while( n-- ){        scanf("%s",type);        if(type[0]!='P' && type[0]!='N') scanf("%d",&pos);        if(type[0]=='M') Move(pos);        else if(type[0]=='I') Insert(pos);        else if(type[0]=='D') Delete(pos);        else if(type[0]=='G') Get(pos);        else if(type[0]=='P') Prev();        else Next();    }    return 0;}void Init(){    NewNode(root,0,' ');    NewNode(ch[root][1],root,' ');    Updata(root);}void NewNode(int &r,int father,char t){    c[r=++total] = t;    pre[r] = father;    ch[r][0] = ch[r][1] = 0;    size[r] = 1;}void Rotate(int r,int way){    int tmp = pre[r];    pre[ch[tmp][!way]=ch[r][way]] = tmp;    if(pre[tmp]) ch[pre[tmp]][ch[pre[tmp]][1]==tmp] = r;    pre[r] = pre[tmp];    pre[ch[r][way]=tmp] = r;    Updata(tmp);Updata(r);Updata(pre[r]);}void Splay(int r,int goal){    int x,y,kind;    while(pre[r] != goal)        if(pre[pre[r]] == goal) Rotate(r,ch[pre[r]][0]==r);        else{            x=pre[r];y=pre[x];kind=ch[y][1]==x;            if(ch[x][kind]==r) Rotate(x,!kind),Rotate(r,!kind);            else Rotate(r,kind),Rotate(r,!kind);        }    if(!goal) root=r;}void Build(int &t,int l,int r,int father){    if(l>r) return;    int mid = (l+r)>>1;    NewNode(t,father,str[mid]);    Build(ch[t][0],l,mid-1,t);    Build(ch[t][1],mid+1,r,t);    Updata(t);}void Updata(int r){    if(!r) return ;    size[r] = size[ch[r][0]]+size[ch[r][1]]+1;}int Order(int key){    int now = root;    while(true)        if(size[ch[now][0]]>=key) now=ch[now][0];        else if(size[ch[now][0]]+1==key) return now;        else key-=(1+size[ch[now][0]]),now=ch[now][1];}void Display(int r){    if(!r) return;    Display(ch[r][0]);    if(r>2) putchar(c[r]);    Display(ch[r][1]);}void Move(int k){    Splay(Order(k+1),0);}void Insert(int k){    for(int i=0;i<k;++i){        str[i] = getchar();        if(str[i]<32 || str[i]>126) --i;    }    Splay(Order(size[ch[root][0]]+2),root);    Build(ch[ch[root][1]][0],0,k-1,ch[root][1]);    Updata(ch[root][1]),Updata(root);}void Delete(int k){    Splay(Order(size[ch[root][0]]+2+k),root);//  printf("<delete>:");Display(ch[ch[root][1]][0]),putchar(10);    ch[ch[root][1]][0] = 0;    Updata(ch[root][1]),Updata(root);}void Get(int k){    Splay(Order(size[ch[root][0]]+2+k),root);    Display(ch[ch[root][1]][0]);    putchar(10);}void Prev(){    Splay(Order(size[ch[root][0]]),0);}void Next(){    Splay(Order(size[ch[root][0]]+2),0);}

Bzoj 1503 代码

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = 100000+50;const int inf = 0x3f3f3f3f;int ch[Size][2],add[Size],pre[Size],data[Size],total[Size],size[Size];int root,tot,n,mx,ans;void Read(int &);void Read(char &);void NewNode(int &,int,int);void Splay(int,int);void Rotate(int,int);void Updata(int);void PushDown(int);void PushAdd(int,int);void Insert(int);void Add(int);int Order(int);int GetPre(int);int GetNxt(int);void Display(int);void Debug();int main(){    NewNode(root,0,-inf);NewNode(ch[root][1],root,inf);Updata(root);    Read(n);Read(mx);    char c;    int t;    while( n-- ){        Read(c);Read(t);        if(c=='I') Insert(t);        else if(c=='A') Add(t);        else if(c=='S') Add(-t);        else printf("%d\n",Order(t+1));    }    printf("%d",ans);    return 0;}void Read(int &in){    char ch;    for(ch=getchar();ch>'9'||ch<'0';ch=getchar()) ;    for(in=0;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0';}void Read(char &ch){    for(ch=getchar();ch>'Z'||ch<'A';ch=getchar());}void NewNode(int &r,int father,int key){    pre[r=++tot] = father;    data[r] = key;    size[r] = total[r] = 1;}void Splay(int r,int goal){    int x,y,kind;    while(pre[r] != goal)        if(pre[pre[r]]==goal) Rotate(r,ch[pre[r]][0]==r);        else{            x=pre[r];y=pre[x];kind=ch[y][1]==x;            if(ch[x][kind]==r) Rotate(x,!kind),Rotate(r,!kind);            else Rotate(r,kind),Rotate(r,!kind);        }    if(!goal) root=r;}void Rotate(int r,int way){    int t = pre[r];    pre[ch[t][!way]=ch[r][way]] = t;    if(pre[t]) ch[pre[t]][ch[pre[t]][1]==t] = r;    pre[r] = pre[t];    pre[ch[r][way]=t] = r;    Updata(t);Updata(r);}void Updata(int r){    if(!r) return ;    size[r] = size[ch[r][0]]+size[ch[r][1]]+total[r];}void PushDown(int r){    if(!r) return ;    if(add[r]){        PushAdd(ch[r][0],add[r]);        PushAdd(ch[r][1],add[r]);        add[r] = 0;    }}void PushAdd(int r,int c){    if(!r) return ;    data[r] += c;    add[r] += c;}void Add(int c){    Splay(GetPre(-inf),0);Splay(GetNxt(inf),root);    PushAdd(ch[ch[root][1]][0],c);    if(c < 0){        Splay(GetNxt(mx),root);        ans += size[ch[ch[root][1]][0]];        ch[ch[root][1]][0] = 0;        Updata(ch[root][1]);Updata(root);    }}void Insert(int x){    if(x < mx) {return ;}    Splay(GetPre(x-1),0);Splay(GetNxt(x+1),root);    if(ch[ch[root][1]][0]) ++size[ch[ch[root][1]][0]],++total[ch[ch[root][1]][0]];    else NewNode(ch[ch[root][1]][0],ch[root][1],x);    Updata(ch[root][1]);Updata(root);}int Order(int k){    if(k>=size[root]) return -1;    int now = root;    while(true){        PushDown(now);        if(size[ch[now][1]]>=k) now=ch[now][1];        else if(size[ch[now][1]]+total[now]>=k) return data[now];        else k-=(size[ch[now][1]]+total[now]),now=ch[now][0];    }}int GetPre(int r){    int now = root;    while(data[now] != r){        PushDown(now);        if(data[now]>r)            if(!ch[now][0]) break;            else now=ch[now][0];        else            if(!ch[now][1]) break;            else now=ch[now][1];    }    PushDown(now);    while(data[now]>r) now=pre[now];    return now;}int GetNxt(int r){    int now = root;    while(data[now] != r){        PushDown(now);        if(data[now]>r)            if(!ch[now][0]) break;            else now=ch[now][0];        else            if(!ch[now][1]) break;            else now=ch[now][1];    }    PushDown(now);    while(data[now]<r) now=pre[now];    return now;}void Display(int r){    if(!r) return ;    PushDown(r);    Display(ch[r][0]);    printf("%d ",data[r]);    Display(ch[r][1]);}void Debug(){    Display(root);putchar(10);}

Bzoj 1552 代码

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const int Size = 100000+50;const LL inf = 0x3f3f3f3f3f3f3f3fLL;int ch[Size][2],size[Size],pre[Size],total,root,rev[Size];LL data[Size],mx[Size],a[Size];void Read(int&);void NewNode(int&,int,LL);void Build(int &,int,int,int);void Splay(int,int);void Rotate(int,int);void Updata(int);void PushRev(int);void PushDown(int);void FindNxt();void Get();void Delete();void Display(int);int main(){    int n;    Read(n);    for(int i=1,x;i<=n;++i){        Read(x);        a[i] = x*100000LL+i;    }    Build(root,1,n,0);    for(int i=1;i<=n;++i){        Get();        if(i != n)            printf("%d ",size[ch[root][0]]+i);        else             printf("%d",size[ch[root][0]]+i);        PushRev(ch[root][0]);        Delete();    }    return 0;}void Read(int &in){    char ch;int f=1;    for(ch=getchar();ch>'9'||ch<'0';ch=getchar()) if(ch=='-') f=-1;    for(in=0;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0';    in *= f;}void NewNode(int &r,int father,LL key){    pre[r=++total] = father;    ch[r][0] = ch[r][1] = rev[r] = 0;    data[r] = key;    size[r] = 1;}void Build(int &node,int l,int r,int father){    if(l > r) return ;    int mid = (l+r)>>1;    NewNode(node,father,a[mid]);    Build(ch[node][0],l,mid-1,node);    Build(ch[node][1],mid+1,r,node);    Updata(node);}void Splay(int r,int goal){    int x,y,kind;    while(pre[r] != goal)        if(pre[pre[r]]==goal)            Rotate(r,ch[pre[r]][0]==r);        else{            x=pre[r];y=pre[x];kind=ch[y][1]==x;            if(ch[x][kind]==r) Rotate(x,!kind),Rotate(r,!kind);            else Rotate(r,kind),Rotate(r,!kind);        }    if(!goal) root=r;}void Rotate(int r,int way){    int t = pre[r];    pre[ch[t][!way]=ch[r][way]] = t;    if(pre[t]) ch[pre[t]][ch[pre[t]][1]==t] = r;    pre[r] = pre[t];    pre[ch[r][way]=t] = r;    Updata(t);Updata(r);Updata(pre[r]);}void Updata(int r){    if(!r) return ;    size[r] = size[ch[r][0]]+size[ch[r][1]]+1;    mx[r] = data[r];    if(ch[r][0]) mx[r] = min(mx[r],mx[ch[r][0]]);    if(ch[r][1]) mx[r] = min(mx[r],mx[ch[r][1]]);}void PushRev(int r){    if(!r) return ;    swap(ch[r][0],ch[r][1]);    rev[r] ^= 1;}void PushDown(int r){    if(rev[r]){        PushRev(ch[r][0]);        PushRev(ch[r][1]);        rev[r] ^= 1;    }}void FindNxt(){    if(!ch[root][1]) return ;    PushDown(root);    int now=ch[root][1];    PushDown(now);    while(ch[now][0]){        now=ch[now][0];        PushDown(now);    }    Splay(now,root);}void Get(){    int now = root;    while(data[now] != mx[now]){        PushDown(now);        if(mx[ch[now][0]]==mx[now]) now=ch[now][0];        else now=ch[now][1];    }    PushDown(now);    Splay(now,0);}void Delete(){    if(!ch[root][1]){        root = ch[root][0];        pre[root] = 0;        return ;    }    if(!ch[root][0]){        root = ch[root][1];        pre[root] = 0;        return ;    }    FindNxt();    pre[ch[root][0]] = ch[root][1];    ch[ch[root][1]][0] = ch[root][0];    root = ch[root][1];    pre[root] = 0;    Updata(root);}void Display(int now){    if(!now) return ;    PushDown(now);    Display(ch[now][0]);    printf("%lld ",data[now]);    Display(ch[now][1]);}

Bzoj 1895 代码

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = 200000+20;const int inf = 0x3f3f3f3f;int ch[Size][2],mx[Size],pre[Size],size[Size],rev[Size],add[Size],data[Size],total,root;int a[Size];char str[20];void Read(int &);void NewNode(int&,int,int);void Build(int&,int,int,int);void Splay(int,int);void Rotate(int,int);int Order(int);void PushRev(int);void PushAdd(int,int);void Updata(int);void PushDown(int);void Insert(int,int);void Delete(int);void Reverse(int,int);void Add(int,int,int);void Revolve(int,int,int);int Min(int,int);void Display(int );int main(){    int n,m,pos1,pos2,c;    Read(n);    for(int i=0;i<n;++i) Read(a[i]);    NewNode(root,0,inf);NewNode(ch[root][1],root,inf);    Build(ch[ch[root][1]][0],0,n-1,ch[root][1]);    Read(m);    for(int i=1;i<=m;++i){        scanf("%s",str);        if(str[0]=='A') Read(pos1),Read(pos2),Read(c),Add(pos1,pos2,c);        else if(str[0]=='I') Read(pos1),Read(c),Insert(pos1,c);        else if(str[0]=='D') Read(pos1),Delete(pos1);        else if(str[0]=='M') Read(pos1),Read(pos2),printf("%d\n",Min(pos1,pos2));        else if(str[3]=='E') Read(pos1),Read(pos2),Reverse(pos1,pos2);        else Read(pos1),Read(pos2),Read(c),Revolve(pos1,pos2,c);    }    return 0;}void Read(int &in){    int f=1;char ch;    for(ch=getchar();ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;    for(in=0;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0';    in *= f;}void NewNode(int &node,int father,int key){    pre[node=++total] = father;    mx[node] = data[node] = key;    size[node] = 1;}void Build(int &node,int l,int r,int father){    if(l>r) return ;    int mid = (l+r)>>1;    NewNode(node,father,a[mid]);    Build(ch[node][0],l,mid-1,node);    Build(ch[node][1],mid+1,r,node);    Updata(node);}void Splay(int node,int goal){    if(node==goal) return ;    int x,y,kind;    while(pre[node] != goal){        if(pre[pre[node]]==goal){            PushDown(pre[node]);PushDown(node);            Rotate(node,ch[pre[node]][0]==node);        }        else{            x=pre[node];y=pre[x];kind=ch[y][1]==x;            PushDown(y);PushDown(x);PushDown(node);            if(ch[x][kind]==node) Rotate(x,!kind),Rotate(node,!kind);            else Rotate(node,kind),Rotate(node,!kind);        }    }    if(!goal) root=node;}void Rotate(int node,int way){    int tmp=pre[node];    pre[ch[tmp][!way]=ch[node][way]] = tmp;    if(pre[tmp]) ch[pre[tmp]][ch[pre[tmp]][1]==tmp] = node;    pre[node] = pre[tmp];    pre[ch[node][way]=tmp] = node;    Updata(tmp),Updata(node);}int Order(int k){    int now=root;    while(true){        PushDown(now);        if(size[ch[now][0]]>=k) now=ch[now][0];        else if(size[ch[now][0]]+1==k) return now;        else k-=(size[ch[now][0]]+1),now=ch[now][1];    }}void PushRev(int node){    if(!node) return ;    swap(ch[node][0],ch[node][1]);    rev[node] ^= 1;}void PushAdd(int node,int key){    if(!node) return ;    mx[node] += key;    data[node] += key;    add[node] += key;}void Updata(int node){    if(!node) return ;    size[node] = size[ch[node][0]]+size[ch[node][1]]+1;    mx[node] = data[node];    if(ch[node][0]) mx[node] = min(mx[ch[node][0]],mx[node]);    if(ch[node][1]) mx[node] = min(mx[ch[node][1]],mx[node]);}void PushDown(int node){    if(add[node]){        PushAdd(ch[node][0],add[node]);        PushAdd(ch[node][1],add[node]);        add[node] = 0;    }    if(rev[node]){        PushRev(ch[node][0]);        PushRev(ch[node][1]);        rev[node] = 0;    }}void Insert(int pos,int key){    Splay(Order(pos+1),0);Splay(Order(pos+2),root);    NewNode(ch[ch[root][1]][0],ch[root][1],key);    Updata(ch[root][1]);Updata(root);}void Delete(int pos){    Splay(Order(pos),0);Splay(Order(pos+2),root);    ch[ch[root][1]][0] = 0;    Updata(ch[root][1]);Updata(root);}void Reverse(int l,int r){    Splay(Order(l),0);Splay(Order(r+2),root);    PushRev(ch[ch[root][1]][0]);}void Add(int l,int r,int c){    Splay(Order(l),0);Splay(Order(r+2),root);    PushAdd(ch[ch[root][1]][0],c);    Updata(ch[root][1]);Updata(root);}void Revolve(int l,int r,int t){    t %= (r-l+1);    if(!t) return ;    Reverse(l,r);    Reverse(l,l+t-1);    Reverse(l+t,r);}int Min(int l,int r){    Splay(Order(l),0);Splay(Order(r+2),root);    return mx[ch[ch[root][1]][0]];}void Display(int node){    if(!node) return ;    PushDown(node);    Display(ch[node][0]);    printf("%d ",data[node]);    Display(ch[node][1]);}

Bzoj 1500 代码

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int Size = 500000+100;const int inf = 0x3f3f3f3f;int ch[Size][2],pre[Size],size[Size],mx[Size],lx[Size],rx[Size];int sum[Size],rev[Size],same[Size],data[Size];int root;int Stack[Size],top;int a[Size];char type[20];void Read(int &);void NewNode(int &,int,int);void Build(int &,int,int,int);void Splay(int,int);void Rotate(int,int);void Updata(int);int Order(int);void PushDown(int);void PushSame(int,int);void PushRev(int);void Insert(int,int);void Delete(int,int);void Rec(int);void MakeSame(int,int,int);void Reverse(int,int);int GetSum(int,int);int MaxSum();void Display(int);void Debug();int main(){    for(int i=Size-1;--i;) Stack[++top] = i;    NewNode(root,0,-inf);NewNode(ch[root][1],root,-inf);Updata(root);    int t,n,pos,tot,c;    Read(n);Read(t);    for(int i=0;i<n;++i) Read(a[i]);    Build(ch[ch[root][1]][0],0,n-1,ch[root][1]);    Updata(ch[root][1]);Updata(root);    while( t-- ){        scanf("%s",type);        if(type[2]!='X') Read(pos),Read(tot);        if(type[2]=='S') Insert(pos,tot);        else if(type[2]=='L') Delete(pos,tot);        else if(type[2]=='K') Read(c),MakeSame(pos,tot,c);        else if(type[2]=='V') Reverse(pos,tot);        else if(type[2]=='T') printf("%d\n",GetSum(pos,tot));        else printf("%d\n",MaxSum());    }    return 0;}void Read(int &in){    char ch;int f=1;    for(ch=getchar();ch>'9'||ch<'0';ch=getchar()) if(ch=='-') f=-1;    for(in=0;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0';    in *= f;}void NewNode(int &r,int father,int key){    pre[r=Stack[top--]] = father;    sum[r] = data[r] = lx[r] = mx[r] = rx[r] = key;    size[r] = 1;    ch[r][0] = ch[r][1] = same[r] = rev[r] = 0;}void Build(int &node,int l,int r,int father){    if(l > r) return ;    int mid = (l+r)>>1;    NewNode(node,father,a[mid]);    Build(ch[node][0],l,mid-1,node);    Build(ch[node][1],mid+1,r,node);    Updata(node);}void Splay(int r,int goal){    int x,y,kind;    while(pre[r] != goal)        if(pre[pre[r]]==goal) Rotate(r,ch[pre[r]][0]==r);        else{            x=pre[r];y=pre[x];kind=ch[y][1]==x;            if(ch[x][kind]==r) Rotate(x,!kind),Rotate(r,!kind);            else Rotate(r,kind),Rotate(r,!kind);        }    if(!goal) root=r;}void Rotate(int r,int way){    int t = pre[r];    pre[ch[t][!way]=ch[r][way]] = t;    if(pre[t]) ch[pre[t]][ch[pre[t]][1]==t] = r;    pre[r] = pre[t];    pre[ch[r][way]=t] = r;    Updata(t);Updata(r);Updata(pre[r]);}void Updata(int r){    if(!r) return ;    size[r] = size[ch[r][0]]+size[ch[r][1]]+1;    sum[r] = sum[ch[r][0]]+sum[ch[r][1]]+data[r];    lx[r] = sum[ch[r][0]]+data[r]+max(0,lx[ch[r][1]]);    if(ch[r][0]) lx[r] = max(lx[r],lx[ch[r][0]]);    rx[r] = sum[ch[r][1]]+data[r]+max(0,rx[ch[r][0]]);    if(ch[r][1]) rx[r] = max(rx[r],rx[ch[r][1]]);    mx[r] = max(0,rx[ch[r][0]])+data[r]+max(0,lx[ch[r][1]]);    if(ch[r][0]) mx[r] = max(mx[r],mx[ch[r][0]]);    if(ch[r][1]) mx[r] = max(mx[r],mx[ch[r][1]]);}int Order(int k){    int now = root;    while(true){        PushDown(now);        if(size[ch[now][0]]>=k) now=ch[now][0];        else if(size[ch[now][0]]+1==k) return now;        else k-=(size[ch[now][0]]+1),now=ch[now][1];    }}void PushDown(int r){    if(same[r]){        PushSame(ch[r][0],data[r]);        PushSame(ch[r][1],data[r]);        same[r] = 0;    }    if(rev[r]){        PushRev(ch[r][0]);        PushRev(ch[r][1]);        rev[r] = 0;    }}void PushSame(int r,int c){    if(!r) return ;    data[r] = c;    sum[r] = c*size[r];    lx[r] = mx[r] = rx[r] = max(sum[r],c);    same[r] = 1;}void PushRev(int r){    if(!r) return ;    swap(lx[r],rx[r]);    swap(ch[r][0],ch[r][1]);    rev[r] ^= 1;}void Insert(int pos,int tot){    for(int i=0;i<tot;++i) Read(a[i]);    Splay(Order(pos+1),0);    Splay(Order(pos+2),root);    Build(ch[ch[root][1]][0],0,tot-1,ch[root][1]);    Updata(ch[root][1]);Updata(root);}void Delete(int pos,int tot){    Splay(Order(pos),0);    Splay(Order(pos+tot+1),root);    Rec(ch[ch[root][1]][0]);    ch[ch[root][1]][0] = 0;    Updata(ch[root][1]);Updata(root);}void Rec(int r){    if(!r) return ;    Stack[++top] = r;    Rec(ch[r][0]);Rec(ch[r][1]);}void MakeSame(int pos,int tot,int c){    Splay(Order(pos),0);    Splay(Order(pos+tot+1),root);    PushSame(ch[ch[root][1]][0],c);    Updata(ch[root][1]);Updata(root);}void Reverse(int pos,int tot){    Splay(Order(pos),0);    Splay(Order(pos+tot+1),root);    PushRev(ch[ch[root][1]][0]);    Updata(ch[root][1]);Updata(root);}int GetSum(int pos,int tot){    Splay(Order(pos),0);    Splay(Order(pos+tot+1),root);    return sum[ch[ch[root][1]][0]];}int MaxSum(){    return mx[root];}void Display(int r){    if(!r) return ;    Display(ch[r][0]);    printf("%d ",data[r]);    Display(ch[r][1]);}void Debug(){    Display(root);    putchar(10);}
0 0
原创粉丝点击