BZOJ3196 3223 3224 二逼平衡树,文艺平衡树,普通平衡树

来源:互联网 发布:小红书 有钱人 知乎 编辑:程序博客网 时间:2024/04/30 15:51

水一水。

上代码:

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;elseGrandpa -> 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);elseRotate(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];elseRank += 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;elseR = 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;elseGrandpa -> 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);elseRotate(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;elsek -= 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;}


0 0
原创粉丝点击