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

版权声明:都是TATQAQ2333大爷教我的 https://blog.csdn.net/u012076197/article/details/50560103

水一水。

上代码:

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;
}


猜你喜欢

转载自blog.csdn.net/u012076197/article/details/50560103