BZOJ3196 3223 3224 二逼平衡樹,文藝平衡樹,普通平衡樹
阿新 • • 發佈:2019-01-14
水一水。
上程式碼:
BZOJ3196:
/* * @Author: duyixian * @Date: 2016-01-13 11:08:18 * @Last Modified by: duyixian * @Last Modified time: 2016-01-15 16:50:16 */ #include "cstdio" #include "cstdlib" #include "iostream" #include "algorithm" #include "cstring" #include "queue" using namespace std; #define MAX_SIZE 100005 #define INF 0x3F3F3F3F #define Eps #define Mod #define Get(x, a) (x ? x -> a : 0) #define Lowbit(x) (x & -x) inline int Get_Int() { int Num = 0, Flag = 1; char ch; do { ch = getchar(); if(ch == '-') Flag *= -1; } while(ch < '0' || ch > '9'); do { Num = Num * 10 + ch - '0'; ch = getchar(); } while(ch >= '0' && ch <= '9'); return Num * Flag; } class Node { public: Node *Child[2], *Father; int Size, Value, Sum; }Nodes[MAX_SIZE * 40]; int Total; class Spaly_Tree { public: Node *Root; inline Node* New(int Value) { Node *x = &Nodes[Total++]; x -> Value = Value; x -> Size = x -> Sum = 1; return x; } inline void Update(Node *x) { x -> Sum = x -> Size + Get(x -> Child[0], Sum) + Get(x -> Child[1], Sum); } inline void Rotate(Node *x) { Node *Father = x -> Father, *Grandpa = Father -> Father; if(!Grandpa) Root = x; else Grandpa -> Child[Grandpa -> Child[1] == Father] = x; int i = Father -> Child[1] == x, j = i ^ 1; if(x -> Child[j]) x -> Child[j] -> Father = Father; Father -> Child[i] = x -> Child[j]; x -> Child[j] = Father; Father -> Father = x; x -> Father = Grandpa; Update(Father); Update(x); } inline void Splay(Node *x, Node *k) { while(x -> Father != k) { Node *Father = x -> Father, *Grandpa = Father -> Father; if(Grandpa != k) if(Grandpa -> Child[1] == Father ^ Father -> Child[1] == x) Rotate(x); else Rotate(Father); Rotate(x); } } inline Node* Find(int Value) { if(!Root) return NULL; Node *x = Root; int i = Value > x -> Value; while(x -> Child[i]) { if(x -> Value == Value) return x; x = x -> Child[i]; i = Value > x -> Value; } return x; } inline Node* Insert(int Value) { if(!Root) return Root = New(Value); Node *x = Find(Value); if(x -> Value == Value) ++x -> Size; else { int i = Value > x -> Value; x -> Child[i] = New(Value); x -> Child[i] -> Father = x; } for(Node *temp = x; temp; temp = temp -> Father) Update(temp); Splay(x, NULL); return x; } inline void Delete(int Value) { Node *x = Find(Value); if(x -> Value == Value) if(x -> Size) { --x -> Size; for(; x; x = x -> Father) Update(x); } } inline int Find_Rank(int Value) { Node *x = Root; int Rank = 0; while(x) { if(Value >= x -> Value) Rank += Get(x -> Child[0], Sum); if(Value == x -> Value) break; if(Value < x -> Value) x = x -> Child[0]; else Rank += x -> Size, x = x -> Child[1]; } return Rank; } }; int N, M; int Value[MAX_SIZE]; class BIT { public: Spaly_Tree Tree[MAX_SIZE]; inline void Insert(int Location, int Value) { while(Location <= N) { Tree[Location].Insert(Value); Location += Lowbit(Location); } } inline void Delete(int Location, int Value) { while(Location <= N) { Tree[Location].Delete(Value); Location += Lowbit(Location); } } inline int Find_Rank(int Location, int Value) { int Rank = 0; while(Location) { Rank += Tree[Location].Find_Rank(Value); Location -= Lowbit(Location); } return Rank; } inline int Find_Rank(int Left, int Right, int Value) { return Find_Rank(Right, Value) - Find_Rank(Left - 1, Value) + 1; } inline int Find_Kth(int Left, int Right, int K) { int L = 0, R = 100000005, M = L + R >> 1; while(M != L && M != R) { int Rank = Find_Rank(Left, Right, M); if(Rank <= K) L = M; else R = M; M = L + R >> 1; } return L; } inline int Find(int Left, int Right, int Value, int Flag) { int temp, Ans; if(Flag == 0) { temp = Find_Rank(Left, Right, Value); Ans = Find_Kth(Left, Right, temp - 1); return Ans; } else { temp = Find_Rank(Left, Right, Value + 1); Ans = Find_Kth(Left, Right, temp); return Ans; } } }BIT; int main() { cin >> N >> M; for(int i = 1; i <= N; ++i) BIT.Insert(i, Value[i] = Get_Int()); while(M--) { int Op = Get_Int(); if(Op == 1) { int Left = Get_Int(), Right = Get_Int(), Val = Get_Int(); printf("%d\n", BIT.Find_Rank(Left, Right, Val)); } else if(Op == 2) { int Left = Get_Int(), Right = Get_Int(), K = Get_Int(); printf("%d\n", BIT.Find_Kth(Left, Right, K)); } else if(Op == 3) { int Position = Get_Int(), Val = Get_Int(); BIT.Delete(Position, Value[Position]); BIT.Insert(Position, Val); Value[Position] = Val; } else { int Left = Get_Int(), Right = Get_Int(), Val = Get_Int(); printf("%d\n", BIT.Find(Left, Right, Val, Op - 4)); } } return 0; }
BZOJ3223:
/* * @Author: duyixian * @Date: 2016-01-13 16:40:15 * @Last Modified by: duyixian * @Last Modified time: 2016-01-14 08:26:52 */ #include "cstdio" #include "cstdlib" #include "iostream" #include "algorithm" #include "cstring" #include "queue" #include "ctime" using namespace std; #define MAX_SIZE 1000005 #define INF 0x3F3F3F3F #define Eps #define Mod #define Get(x, a) (x ? x -> a : 0) inline int Get_Int() { int Num = 0, Flag = 1; char ch; do { ch = getchar(); if(ch == '-') Flag *= -1; } while(ch < '0' || ch > '9'); do { Num = Num * 10 + ch - '0'; ch = getchar(); } while(ch >= '0' && ch <= '9'); return Num * Flag; } class Node { public: Node *Child[2], *Father; int Value, Size; bool Reverse; }Nodes[MAX_SIZE]; int Total, N, M; int A[MAX_SIZE]; class Splay_Trree { public: Node *Root; inline Node* New(int Value) { Node *x = &Nodes[Total++]; x -> Value = Value; x -> Size = 1; return x; } inline void Push_Down(Node *x) { if(!(x -> Reverse)) return; swap(x -> Child[0], x -> Child[1]); x -> Reverse = 0; if(x -> Child[0]) x -> Child[0] -> Reverse ^= 1; if(x -> Child[1]) x -> Child[1] -> Reverse ^= 1; } inline void Update(Node *x) { Push_Down(x); x -> Size = 1 + Get(x -> Child[0], Size) + Get(x -> Child[1], Size); } inline void Rotate(Node *x) { Push_Down(x -> Father); Push_Down(x); Node *Father = x -> Father, *Grandpa = Father -> Father; if(!Grandpa) Root = x; else Grandpa -> Child[Grandpa -> Child[1] == Father] = x; int i = Father -> Child[1] == x, j = i ^ 1; if(x -> Child[j]) x -> Child[j] -> Father = Father; Father -> Child[i] = x -> Child[j]; x -> Child[j] = Father; Father -> Father = x; x -> Father = Grandpa; Update(Father); Update(x); } inline void Splay(Node *x, Node *k) { while(x -> Father != k) { Node *Father = x -> Father, *Grandpa = Father -> Father; if(Grandpa != k) if(Grandpa -> Child[1] == Father ^ Father -> Child[1] == x) Rotate(x); else Rotate(Father); Rotate(x); } } inline void Insert(int Value) { if(!Root) { Root = New(Value); return; } Node *x = Root; int i = Value > x -> Value; while(x -> Child[i]) { x = x -> Child[i]; i = Value > x -> Value; } x -> Child[i] = New(Value); x -> Child[i] -> Father = x; for(Node *temp = x; temp; temp = temp -> Father) Update(temp); } inline Node* Find_Kth(int k) { Node *x = Root; while(k) { Push_Down(x); if(Get(x -> Child[0], Size) >= k) x = x -> Child[0]; else if(Get(x -> Child[0], Size) + 1 == k) return x; else k -= Get(x -> Child[0], Size) + 1, x = x -> Child[1]; } } inline void Reverse(int Right, int Left) { Node *L = Find_Kth(Left - 1), *R = Find_Kth(Right + 1); Splay(L, NULL); Splay(R, L); R -> Child[0] -> Reverse ^= 1; } }Tree; int main() { cin >> N >> M; for(int i = 0; i <= N + 1; ++i) A[i] = i; for(int i = 0; i <= N + 1; ++i) swap(A[i], A[rand() % (N + 2)]); for(int i = 0; i <= N + 1; ++i) Tree.Insert(A[i]); while(M--) Tree.Reverse(Get_Int() + 1, Get_Int() + 1); for(int i = 1; i <= N; ++i) printf("%d ",Tree.Find_Kth(i + 1) -> Value); return 0; }
BZOJ3224:
/* * @Author: duyixian * @Date: 2016-01-16 10:18:28 * @Last Modified by: duyixian * @Last Modified time: 2016-01-16 19:19:36 */ #include "cstdio" #include "cstdlib" #include "iostream" #include "algorithm" #include "cstring" #include "queue" #include "cmath" using namespace std; #define MAX_SIZE #define INF 0x3F3F3F3F #define Eps #define Mod #define Get(x, a) (x ? x -> a : 0) #define Alpha 0.75 inline int Get_Int() { int Num = 0, Flag = 1; char ch; do { ch = getchar(); if(ch == '-') Flag *= -1; } while(ch < '0' || ch > '9'); do { Num = Num * 10 + ch - '0'; ch = getchar(); } while(ch >= '0' && ch <= '9'); return Num * Flag; } class Node { public: Node *Child[2], *Father; int Size, MaxSize, Value; bool Exist; inline void Update() { Size = Exist + Get(Child[0], Size) + Get(Child[1], Size); MaxSize = max(MaxSize, Size); } inline bool UnBalanced() { return Get(Child[0], Size) > Alpha * Size || Get(Child[1], Size) > Alpha * Size; } }; class Scapegoat_Tree { public: Node *Root, *Good; vector<Node*> temp; inline Node* New(int Value) { Node *x = (Node*)malloc(sizeof(Node)); x -> Size = x -> MaxSize = x -> Exist = 1; x -> Value = Value; x -> Child[0] = x -> Child[1] = x -> Father = NULL; return x; } Scapegoat_Tree() { Good = New(INF); } Node* Rebuild(int Left, int Right, vector<Node*> &temp, Node *Father) { if(Left > Right) return NULL; int Mid = Left + Right >> 1; Node *x = temp[Mid]; x -> Father = Father; x -> Child[0] = Rebuild(Left, Mid - 1, temp, x); x -> Child[1] = Rebuild(Mid + 1, Right, temp, x); x -> Size = x -> MaxSize = Right - Left + 1; return x; } inline void Rebuild(Node *x) { Node *Father = x -> Father; Travel(x, temp); if(Father) Father -> Child[Father -> Child[1] == x] = Rebuild(0, temp.size() - 1, temp, Father); else Root = Rebuild(0, temp.size() - 1, temp, Father); temp.clear(); } void Travel(Node *x, vector<Node*> &temp) { if(!x) return; Travel(x -> Child[0], temp); if(x -> Exist) temp.push_back(x); Travel(x -> Child[1], temp); if(!x -> Exist) free(x); } Node* Insert_and_Find_Scapegoat_if_Need(Node *x, int Value, int Depth) { int i = Value > x -> Value; if(x -> Child[i]) { Node *Scapegoat = Insert_and_Find_Scapegoat_if_Need(x -> Child[i], Value, Depth + 1); x -> Update(); if(Scapegoat) return Scapegoat; else return x -> UnBalanced() ? x : NULL; } else { x -> Child[i] = New(Value); x -> Child[i] -> Father = x; x -> Update(); return Depth <= log(Root -> Size) / log(1 / Alpha) ? Good : NULL; } } inline void Insert(int Value) { if(!Root) { Root = New(Value); return; } Node *Scapegoat = Insert_and_Find_Scapegoat_if_Need(Root, Value, 1); if(Scapegoat != Good && Scapegoat) Rebuild(Scapegoat); } inline int Find_Rank(int Value) { Node *x = Root; int Rank = 0; while(x) if(Value > x -> Value) Rank += Get(x -> Child[0], Size) + x -> Exist, x = x -> Child[1]; else x = x -> Child[0]; return Rank + 1; } inline Node* Find_Kth(int k) { Node *x = Root; while(k && x) if(Get(x -> Child[0], Size) >= k) x = x -> Child[0]; else if(Get(x -> Child[0], Size) + x -> Exist >= k) return x; else k -= Get(x -> Child[0], Size) + x -> Exist, x = x -> Child[1]; return x; } inline void Delete(int Value) { int Rank = Find_Rank(Value); Node *x = Find_Kth(Rank); if(x -> Value == Value && x -> Exist) { x -> Exist = 0; if(Root -> Size - 1 <= Alpha * Root -> MaxSize) Rebuild(Root); else for(; x; x = x -> Father) x -> Update(); } } inline Node* Find(int Value, int Flag) { if(Flag) { int temp = Find_Rank(Value + 1); Node* Ans = Find_Kth(temp); return Ans; } else { int temp = Find_Rank(Value); Node* Ans = Find_Kth(temp - 1); return Ans; } } }Tree; int N; int main() { cin >> N; int Op, x; while(N--) { Op = Get_Int(), x = Get_Int(); if(Op == 1) Tree.Insert(x); else if(Op == 2) Tree.Delete(x); else if(Op == 3) printf("%d\n", Tree.Find_Rank(x)); else if(Op == 4) printf("%d\n", Tree.Find_Kth(x) -> Value); else printf("%d\n", Tree.Find(x, Op - 5) -> Value); } return 0; }