立flag以后滚去复习会考
然后会考一坨翔
然后边颓边写,边颓边改......然后就过了
然后发现跑的还挺快
顺便YM在THU虐场的faebdc
----------------------------------------------------------
Splay对于区间的操作就是用子树来表示区间
然后一个很好的性质是无论怎么转小的总是在左边
于是用相对位置来表示在数组中的下标
最大子段和比较蛋疼
要考虑好多情况
Reverse的时候一定不要忘记swap(LMax, RMax)!!!!!!!!!!
建树用了递归(我很弱)
如果还有问题或者觉得代码风格鬼畜请在下面留言
说实话数据结构题的题解真的不必要......
被坑的地方还是要发出来的
还有GET-SUM的区间长度可能是0
Code:
#include <cstdio>
#include <queue>
using namespace std;
queue<int> Q;
struct Splay_Tree
{
Splay_Tree *F, *Ls, *Rs;
int Size, Reverse, All, Sum, Key, LMax, RMax, Max;
inline void Clear()
{
Size = Reverse = Sum = Key = LMax = RMax = Max = 0;
F = Ls = Rs = NULL;
All = 23333;
}
inline void Init(int x)
{
Key = Sum = LMax = RMax = Max = x;
Size = 1;
}
inline void Update()
{
Pushdown();
// puts("");
// Debug();
Sum = Key, Size = 1;
Max = LMax = RMax = Key;
if (Ls && Rs)
{
Ls->Pushdown();
Rs->Pushdown();
Size += Ls->Size, Sum += Ls->Sum;
Size += Rs->Size, Sum += Rs->Sum;
LMax = max(max(max(Ls->LMax, Ls->Sum+Key), Ls->Sum+Key+Rs->LMax), Ls->Sum+Key+Rs->Sum);
RMax = max(max(max(Rs->RMax, Rs->Sum+Key), Rs->Sum+Key+Ls->RMax), Rs->Sum+Key+Ls->Sum);
Max = max(max(max(max(max(max(max(Key, Ls->RMax+Key+Rs->LMax), Ls->RMax+Key), Ls->Max), Rs->Max), Key+Rs->LMax), LMax), RMax);
return;
}
if (Ls)
{
Ls->Pushdown();
Size += Ls->Size, Sum += Ls->Sum;
LMax = max(Ls->LMax, Ls->Sum+Key);
RMax = max(max(Ls->RMax+Key, Ls->Sum+Key), Key);
Max = max(max(Ls->Max, RMax), LMax);
return;
}
if (Rs)
{
Rs->Pushdown();
Size += Rs->Size, Sum += Rs->Sum;
RMax = max(Rs->RMax, Rs->Sum+Key);
LMax = max(max(Rs->LMax+Key, Rs->Sum+Key), Key);
Max = max(max(Rs->Max, RMax), LMax);
return;
}
}
inline void Zig()
{
Pushdown();
if (F)
{
Splay_Tree *p = F;
p->Ls = Rs;
if (Rs)Rs->F = p;
Rs = p;
F = p->F;
p->F = this;
p->Update();
Update();
if (F)
{
if (p == F->Ls)
F->Ls = this;
else
F->Rs = this;
F->Update();
}
}
else
puts("´óɵ±Æ");
}
inline void Zag()
{
Pushdown();
if (F)
{
Splay_Tree *p = F;
p->Rs = Ls;
if (Ls)Ls->F = p;
Ls = p;
F = p->F;
p->F = this;
p->Update();
Update();
if (F)
{
if (p == F->Ls)
F->Ls = this;
else
F->Rs = this;
F->Update();
}
}
else
puts("´óɵ±Æ");
}
inline void Pushdown()
{
if (Reverse)
{
Reverse = 0;
swap(Ls, Rs);
swap(LMax, RMax);
if (Ls)Ls->Reverse ^= 1;
if (Rs)Rs->Reverse ^= 1;
}
if (All != 23333)
{
Key = All;
Sum = Size * All;
if (All > 0)
LMax = RMax = Max = Sum;
else
LMax = RMax = Max = All;
if (Ls)Ls->All = All;
if (Rs)Rs->All = All;
All = 23333;
}
}
inline void Debug()
{
Pushdown();
if (Ls)Ls->Debug();
printf("%d ", Key);
if (Rs)Rs->Debug();
}
}*Root, T[500001];
int n, m, Number[200001];
inline Splay_Tree *New(int x)
{
if (Q.empty())
{
puts("´óɵ±Æ");
return NULL;
}
Splay_Tree *p = &T[Q.front()];
Q.pop();
p->Clear();
p->Init(x);
return p;
}
inline void Splay(Splay_Tree *s, Splay_Tree *t)
{
if (!s || s == t)return;
if (t == NULL)Root = s;
while (s->F != t)
{
s->Pushdown();
if (s->F->F == t)
{
if (s == s->F->Ls)
s->Zig();
else
s->Zag();
}
else
{
if (s->F->F->Ls == s->F)
{
if (s->F->Ls == s)
s->F->Zig(), s->Zig();
else
s->Zag(), s->Zig();
}
else
{
if (s->F->Ls == s)
s->Zig(), s->Zag();
else
s->F->Zag(), s->Zag();
}
}
}
}
inline Splay_Tree *Select(Splay_Tree *p, int x)
{
if (!p)return p;
p->Pushdown();
int now(1);
if (p->Ls)now += p->Ls->Size;
if (x == now)
return p;
if (x > now)
return Select(p->Rs, x-now);
return Select(p->Ls, x);
}
inline Splay_Tree *Build(int l, int r, int *a)
{
if (l > r)return 0;
int mid = (l + r) >> 1;
Splay_Tree *p = New(a[mid]);
p->Ls = Build(l, mid-1, a), p->Rs = Build(mid+1, r, a);
if (p->Ls)p->Ls->F = p;
if (p->Rs)p->Rs->F = p;
p->Update();
return p;
}
inline void Insert(int x, int len, int *a)
{
n += len;
if (!Root)
{
Root = Build(1, len, a);
return;
}
if (!x)
{
Splay(Select(Root, 1), Root->F);
Root->Ls = Build(1, len, a);
Root->Update();
Root->Ls->F = Root;
return;
}
if (x == n-len)
{
Splay(Select(Root, x), Root->F);
Root->Rs = Build(1, len, a);
Root->Update();
Root->Rs->F = Root;
return;
}
Splay(Select(Root, x), Root->F), Splay(Select(Root, x+1), Root);
Root->Rs->Ls = Build(1, len, a);
Root->Rs->Ls->F = Root->Rs;
Root->Pushdown();
Root->Rs->Pushdown();
//Splay(Root->Rs->Ls, Root->F);
Root->Rs->Update();
Root->Update();
}
inline void Delete(Splay_Tree *s)
{
if (s->Ls)
Delete(s->Ls), s->Ls = NULL;
if (s->Rs)
Delete(s->Rs), s->Rs = NULL;
Q.push(s-&T[0]);
n--;
}
inline void Delete(int l, int r)
{
if (l == 1 && r == n)
{
Delete(Root);
Root = NULL;
return;
}
if (l == 1)
{
Splay(Select(Root, r+1), Root->F);
Delete(Root->Ls);
Root->Ls = NULL;
Root->Update();
return;
}
if (r == n)
{
Splay(Select(Root, l-1), Root->F);
Delete(Root->Rs);
Root->Rs = NULL;
Root->Update();
return;
}
Splay(Select(Root, l-1), Root->F);
Splay(Select(Root, r+1), Root);
Delete(Root->Rs->Ls);
Root->Rs->Ls = NULL;
Root->Rs->Update();
Root->Update();
}
inline void MakeSame(int l, int r, int x)
{
if (l == 1 && r == n)
{
Root->All = x;
return;
}
else
if (l == 1)
{
Splay(Select(Root, r+1), Root->F);
Root->Ls->All = x;
Splay(Root->Ls, Root->F);
return;
}
else
if (r == n)
{
Splay(Select(Root, l-1), Root->F);
Root->Rs->All = x;
Splay(Root->Rs, Root->F);
return;
}
Splay(Select(Root, l-1), Root->F);
Splay(Select(Root, r+1), Root);
Root->Rs->Ls->All = x;
Splay(Root->Rs->Ls, Root->F);
}
inline void Reverse(int l, int r)
{
if (l == 1 && r == n)
{
Root->Reverse ^= 1;
return;
}
else
if (l == 1)
{
Splay(Select(Root, r+1), Root->F);
Root->Ls->Reverse ^= 1;
Splay(Root->Ls, Root->F);
return;
}
else
if (r == n)
{
Splay(Select(Root, l-1), Root->F);
Root->Rs->Reverse ^= 1;
Splay(Root->Rs, Root->F);
return;
}
Splay(Select(Root, l-1), Root->F);
Splay(Select(Root, r+1), Root);
Root->Rs->Ls->Reverse ^= 1;
Splay(Root->Rs->Ls, Root->F);
}
inline int GetSum(int l, int r)
{
if (l == 1 && r == n)
return Root->Sum;
else
if (l == 1)
{
Splay(Select(Root, r+1), Root->F);
return Root->Ls->Sum;
}
else
if (r == n)
{
Splay(Select(Root, l-1), Root->F);
return Root->Rs->Sum;
}
Splay(Select(Root, l-1), Root->F);
Splay(Select(Root, r+1), Root);
return Root->Rs->Ls->Sum;
}
inline int MaxSum()
{
Root->Pushdown();
return Root->Max;
}
inline void Debug(){if (Root)Root->Debug(), puts("");}
char c, ch[100];
inline void read(int &x)
{
int opt(1);
for (c = getchar();c > '9' || c < '0';c = getchar())
if (c == '-')opt = -1;
for (x = 0;c >= '0' && c <= '9';c = getchar())
x = (x << 3) + (x << 1) + c - '0';
x *= opt;
}
int main()
{
// freopen("a.in", "r", stdin);
// freopen("a.out", "w", stdout);
int i, j, l, r, mid, len, pos;
for (i = 0;i < 500001; ++i)Q.push(i);
read(n), read(m);
for (i = 1;i <= n;read(Number[i]), ++i);
Root = Build(1, n, Number);
for (c = getchar();m;m--, c = getchar())
{
// Debug();
switch (c)
{
case ('I') :
{
read(pos), read(len);
for (i = 1;i <= len;read(Number[i]), ++i);
Insert(pos, len, Number);
// printf("INSERT %d %d\n", pos, len);
break;
}
case ('D') :
{
read(pos), read(len);
Delete(pos, pos+len-1);
// printf("DELETE %d %d\n", pos, len);
break;
}
case ('M') :
{
c = getchar();
if (getchar() == 'K')
{
for (c = getchar();c != '-';c = getchar());
read(pos), read(len), read(mid);
MakeSame(pos, pos+len-1, mid);
// printf("MAKE-SAME %d %d %d\n", pos, len, mid);
}
else
{
for (c = getchar();c != '\n';c = getchar());
printf("%d\n", MaxSum());
}
break;
}
case ('R') :
{
read(pos), read(len);
Reverse(pos, pos+len-1);
// printf("REVERSE %d %d\n", pos, len);
break;
}
case ('G') :
{
for (c = getchar();c != '-';c = getchar());
read(pos), read(len);
if (!len)
{
puts("0");
continue;
}
// printf("GET-SUM %d %d ", pos, len);
printf("%d\n", GetSum(pos, pos+len-1));
break;
}
}
}
return 0;
}