poj 3580 splay tree

来源:互联网 发布:mac无法格式化u盘 编辑:程序博客网 时间:2024/05/17 10:40

splay tree 的孩子父亲关系 既可以是 大小的偏序关系 ,也可以是位置的偏序关系~~~

这道题用的是位置的偏序关系~~~

#include <stdio.h>   #include <iostream>#include <string.h>   #include <cmath>#include <algorithm>   #define fr(i,s,n) for(int i=s;i<n;++i)#define _fr(i,n,s) for(int i=n-1;i>=s;--i)#define fi freopen("in.txt","r",stdin)#define cl(a) memset(a,0,sizeof(a))using namespace std;typedef long long ll;const int N=100010;const int INF = 0x7fffffff;class Spt{public:int t;struct Spt_node{int val,siz,laz,mn;//sumbool is_rev;Spt_node *pa,*lc,*rc;}  node[N<<1] , *root,*nil;public:Spt(){nil = new Spt_node();nil->siz = t =0;nil->val  = nil->mn = INF;nil->lc = nil->rc = nil->pa = nil;}/****************************************************/inline Spt_node * new_node(Spt_node *pa,const int val){node[t].mn = node[t].val = val;node[t].siz = 1;node[t].laz = 0;node[t].pa = pa;node[t].lc = node[t].rc = nil;node[t].is_rev = 0;return &node[t++];}Spt_node * build(int l , int r , Spt_node *pa , int arr[]){if (l > r) return nil;int m = (l+r) >> 1;Spt_node * x = new_node(pa , arr[m]);x->lc = build(l,m-1,x,arr);x->rc = build(m + 1,r ,x,arr);up(x);return x;}inline void zig(Spt_node *pos){Spt_node *p = pos->pa;down(p->rc);down(pos->lc);down(pos->rc);p->lc = pos->rc; p->lc->pa = p;pos->rc = p; pos->pa = p->pa;if (p->pa->lc == p) p->pa->lc = pos;else p->pa->rc = pos;p->pa = pos;up(p); up(pos);if(root == p) root = pos;}inline void zag(Spt_node *pos){Spt_node *p = pos->pa;down(p->lc);down(pos->lc);down(pos->rc);p->rc = pos->lc; p->rc->pa = p;pos->lc = p; pos->pa = p->pa;if (p->pa->lc == p) p->pa->lc = pos;else p->pa->rc = pos;p->pa = pos;up(p); up(pos);if(root == p) root = pos;}inline void splay(Spt_node *pos , Spt_node *root){  //这里的root是指要旋转到的根 down( pos);while(pos->pa != root){if (pos->pa->pa == root) {if (pos->pa->lc == pos) zig(pos);else zag(pos);}else if (pos->pa->pa->lc == pos->pa){if (pos->pa->lc == pos) zig(pos->pa),zig(pos);else zag(pos),zig(pos);}else{if (pos->pa->lc == pos) zig(pos),zag(pos);else zag(pos->pa),zag(pos);}}}inline void find(int k,Spt_node *pos){  //将k处的节点旋转到posSpt_node * p = root;down(p);while(k != p->lc->siz + 1){if (k <= p->lc->siz) p = p->lc;else k -= p->lc->siz +1 ,p = p->rc;down(p);}splay(p,pos);}/************/inline void up(Spt_node * pos){if (pos == nil) return;pos->siz = pos->lc->siz + pos->rc->siz + 1;pos->mn = min(pos->val,min(pos->lc->mn,pos->rc->mn));}inline void down(Spt_node * pos){if (pos == nil) return;if (pos->is_rev){swap(pos->lc,pos->rc);pos->lc->is_rev ^= true;pos->rc->is_rev ^= true;pos->is_rev = 0;}if (pos->laz){pos->val += pos->laz;pos->mn += pos->laz;pos->lc->laz += pos->laz;pos->rc->laz += pos->laz;pos->laz = 0;}}/***********/void build(int arr[],int n){ int m = (n >> 1);root = new_node( nil, arr[m]);root->lc = build(0,m-1,root,arr);root->rc = build(m+1, n, root ,arr);up(root);}inline void add(int l,int r,int d){find(l,nil);//因为多加了两个收尾节点所以这里的find 是旋转l前一个find(r+2,root);root->rc->lc->laz += d;}inline void ins(int pos,int d){find(pos+1,nil);find(pos+2,root);root->rc->lc = new_node(root->rc,d);}inline void del(int pos){find(pos,nil);find(pos+2,root);root->rc->lc = nil;}inline int getmn(int l,int r){find(l,nil);find(r+2,root);down(root->rc->lc);return root->rc->lc->mn;}inline void reverse(int l,int r){find(l,nil);find(r+2,root);root->rc->lc->is_rev ^= true;}inline void revolve(int l,int r,int T){int len = r - l + 1;T = ((T % len) + len) % len;if (T){find(r - T + 1,nil);find(r + 2,root);Spt_node *tmp = root->rc->lc;root->rc->lc = nil;find(l,nil);find(l+1,root);root->rc->lc = tmp;tmp->pa = root->rc;}}/****************/void disp(const Spt_node * root){if (root->lc != nil){cout<<root->val<<"的左孩子是:"<<root->lc->val<<"min是"<<root->lc->siz<<endl;disp(root->lc);}if (root ->rc != nil){cout<<root->val<<"的右孩子是:"<<root->rc->val<<"min是"<<root->rc->siz<<endl;disp(root->rc);}}}spt;int arr[N];int main(){int n,m; char op[20];scanf("%d", &n);fr(i,1,n+1) scanf("%d",&arr[i]);arr[0] = arr[n+1] = INF;spt.build(arr , n+1);scanf("%d",&m);int l,r,d,T;fr(i,0,m){scanf("%s",op);switch(op[0]){case  'A' :scanf("%d%d%d",&l,&r,&d);spt.add(l,r,d);break;case 'R' :if('E' == op[3]){scanf("%d%d", &l, &r);spt.reverse(l, r);}else{scanf("%d%d%d", &l, &r,&T);spt.revolve(l,r,T);}break;case 'I' :scanf("%d%d", &l, &d);spt.ins(l,d);break;case 'D' :scanf("%d", &l);spt.del(l);break;case 'M' :scanf("%d%d", &l, &r);printf("%d\n",spt.getmn(l,r));}}return 0;}