BZOJ 1500 Splay 全操作

Posted on 2016-06-16 09:12  yyjxx2010xyu  阅读(117)  评论(0编辑  收藏  举报

好久没写splay了,写一发(写了一节课,调了一节课)

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <algorithm>
  5 #include <vector>
  6 #include <map>
  7 #include <set>
  8 #include <stack>
  9 #define mp make_pair
 10 #define pa pair<int,int>
 11 #define pb push_back
 12 #define fi first
 13 #define se second
 14 #define Key Root->ch[1]->ch[0]
 15 using namespace std;
 16 inline void Get_Int(int &x)
 17 {
 18     x=0; register char ch=getchar(); int f=1;
 19     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
 20     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} x*=f;
 21 }
 22 inline void Put_Int(int x)
 23 {
 24     char ch[20]; register int top=0;
 25     if (x<0) putchar('-'),x=-x;
 26     if (x==0) ch[++top]='0';
 27     while (x) ch[++top]=x%10+'0',x/=10;
 28     while (top) putchar(ch[top--]); putchar('\n');
 29 }
 30 inline int Max(int x,int y) {return x>y?x:y;}
 31 inline int Max3(int x,int y,int z) {return Max(x,Max(y,z));}
 32 inline void Swap(int &x,int &y) {int t=x;x=y;y=t;}
 33 inline bool StrCmp(char S1[],char S2[]) {for (int i=0;i<4;i++) if (S1[i]!=S2[i]) return false; return true;}
 34 //=============================================
 35 const int Maxn=600010;
 36 const int Inf=0x3f3f3f3f;
 37 int a[Maxn],pos,tot,c,n,m,Point;
 38 char str[30];
 39 struct Node
 40 {
 41     int lx,rx,mx,sum,size,key,rev,same;
 42     Node * pre,* ch[2];
 43     inline int d() {return this->pre->ch[1]==this;}
 44     inline void Setc(Node * r,int d) {r->pre=this; this->ch[d]=r;}
 45 };
 46 inline void Swap(Node *&x,Node *&y) {Node * T=x;x=y;y=T;}
 47 Node Memory[Maxn],* port=Memory,* tmp[Maxn],* Bin[Maxn],* null=port++,* Root;
 48 inline Node * NewNode(Node * f,int v)
 49 {
 50     Node * ret;
 51     if (Point) ret=Bin[Point--]; else ret=port++; 
 52     ret->ch[0]=ret->ch[1]=null;
 53     ret->size=1,ret->pre=f;
 54     ret->key=ret->lx=ret->rx=ret->mx=ret->sum=v;
 55     ret->same=ret->rev=0;
 56     return ret;
 57 }
 58 inline void Get_Rev(Node * x)
 59 {
 60     if (x==null) return;
 61     Swap(x->ch[0],x->ch[1]);
 62     Swap(x->lx,x->rx);
 63     x->rev^=1;
 64 }
 65 inline void Get_Same(Node * x,int v)
 66 {
 67     if (x==null) return;
 68     x->key=v; 
 69     x->sum=x->size*v;
 70     x->lx=x->rx=x->mx=Max(v,x->size*v);
 71     x->same=1;
 72 }
 73 inline void Push_Up(Node * x)
 74 {
 75     if (x==null) return;
 76     x->size=x->ch[0]->size+x->ch[1]->size+1;
 77     x->sum=x->ch[0]->sum+x->ch[1]->sum+x->key;
 78     x->lx=Max(x->ch[0]->lx,x->ch[0]->sum+x->key+Max(x->ch[1]->lx,0));
 79     x->rx=Max(x->ch[1]->rx,x->ch[1]->sum+x->key+Max(x->ch[0]->rx,0));
 80     x->mx=Max3(x->ch[0]->mx,x->ch[1]->mx,Max(x->ch[0]->rx,0)+x->key+Max(x->ch[1]->lx,0));
 81 }
 82 inline void Push_Down(Node * x)
 83 {
 84     if (x==null) return;
 85     if (x->rev)
 86     {
 87         Get_Rev(x->ch[0]);
 88         Get_Rev(x->ch[1]);
 89         x->rev=0;
 90     }
 91     if (x->same)
 92     {
 93         Get_Same(x->ch[0],x->key);
 94         Get_Same(x->ch[1],x->key);
 95         x->same=0;
 96     }
 97 }
 98 Node * Build(int l,int r,Node * f)
 99 {
100     if (l>r) return null;
101     int mid=(l+r)>>1;
102     Node * ret=NewNode(f,a[mid]);
103     ret->ch[0]=Build(l,mid-1,ret);
104     ret->ch[1]=Build(mid+1,r,ret);
105     Push_Up(ret);
106     return ret;
107 }
108 inline void Init()
109 {
110     null->ch[0]=null->ch[1]=null->pre=null;
111     null->size=null->key=null->sum=null->same=null->rev=0;
112     null->lx=null->rx=null->mx=-Inf; 
113     Root=NewNode(null,-1);
114     Root->ch[1]=NewNode(Root,-1);
115     for (int i=1;i<=n;i++) Get_Int(a[i]);
116     Key=Build(1,n,Root->ch[1]);
117     Push_Up(Root->ch[1]),Push_Up(Root);
118 }
119 //=========================================================
120 inline void Rotate(Node * x)
121 {
122     Node * y=x->pre; int d=x->d();
123     y->pre->Setc(x,y->d());
124     y->Setc(x->ch[!d],d);
125     x->Setc(y,!d);
126     Push_Up(y);
127 }
128 void Splay(Node * x,Node * Goal)
129 {
130     int s=1; tmp[1]=x; Node * r=x;
131     while (r->pre!=null) tmp[++s]=r=r->pre;
132     while (s) Push_Down(tmp[s--]);
133     while (x->pre!=Goal)
134         if (x->pre->pre==Goal) Rotate(x); else 
135             (x->pre->d()==x->d())?(Rotate(x->pre),Rotate(x)):(Rotate(x),Rotate(x));
136     Push_Up(x);
137     if (Goal==null) Root=x;
138 }
139 //===========================================================
140 Node * Get_K(Node * x,int k)
141 {
142     Push_Down(x);
143     int t=x->ch[0]->size+1;
144     if (t==k) return x;
145     if (t>k) return Get_K(x->ch[0],k);
146     else return Get_K(x->ch[1],k-t);
147 }
148 inline void Handle(int pos,int tot)
149 {
150     Splay(Get_K(Root,pos),null);
151     Splay(Get_K(Root,pos+tot+1),Root);
152 }
153 inline void Insert()
154 {
155     Get_Int(pos),Get_Int(n);
156     Handle(pos+1,0);
157     for (int i=1;i<=n;i++) Get_Int(a[i]);
158     Key=Build(1,n,Root->ch[1]);
159     Push_Up(Root->ch[1]),Push_Up(Root);
160 }
161 void Erase(Node * x)
162 {
163     if (x==null) return;
164     Erase(x->ch[0]),Erase(x->ch[1]);
165     Bin[++Point]=x;
166 }
167 inline void Delete()
168 {
169     Get_Int(pos),Get_Int(tot);
170     Handle(pos,tot);
171     Erase(Key); Key->pre=null; Key=null;
172     Push_Up(Root->ch[1]),Push_Up(Root);
173 }
174 inline void Same()
175 {
176     Get_Int(pos),Get_Int(tot),Get_Int(c);
177     Handle(pos,tot);
178     Get_Same(Key,c);
179     Push_Up(Root->ch[1]),Push_Up(Root);
180 }
181 inline void Rev()
182 {
183     Get_Int(pos),Get_Int(tot);
184     Handle(pos,tot);
185     Get_Rev(Key);
186     Push_Up(Root->ch[1]),Push_Up(Root);
187 }
188 inline void Sum()
189 {
190     Get_Int(pos),Get_Int(tot);
191     Handle(pos,tot);
192     Put_Int(Key->sum);
193 }
194 inline void MaxSum()
195 {
196     Handle(1,Root->size-2);
197     Put_Int(Key->mx);
198 }
199 void InOrder(Node * x)
200 {
201     if (x==null) return;
202     Push_Down(x);
203     InOrder(x->ch[0]);
204     printf("%d ",x->key);
205     InOrder(x->ch[1]);
206 }
207 
208 int main()
209 {
210     Get_Int(n),Get_Int(m);
211     Init();
212     for (int i=1;i<=m;i++)
213     {
214         scanf("%s",str);
215         if (StrCmp(str,"INSERT")) Insert();
216         if (StrCmp(str,"DELETE")) Delete();
217         if (StrCmp(str,"MAKE-SAME")) Same();
218         if (StrCmp(str,"REVERSE")) Rev();
219         if (StrCmp(str,"GET-SUM")) Sum();
220         if (StrCmp(str,"MAX-SUM")) MaxSum();
221     }
222     return 0;
223 }
傻逼200+系列..