版权声明:都是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;
}