题目大意
有一个序列,两种操作。
CUT a b c:把提取出a~b这段区间,插入到剩下的第c个数后。
FLIP a b:翻转a~b这段区间。
共有300000个数,300000个操作。
我的做法
splay
CUT就是三次split和三次merge
FLIP就是两次split,一次reverse和两次merge
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct tree
{
tree *s[2];
bool rev;
int sum;
int v;
tree()
{
rev=0;
v=sum=0;
s[0]=s[1]=0;
}
};
tree *root;
void push(tree *&p)
{
if(!p||!p->rev)
return;
swap(p->s[0],p->s[1]);
if(p->s[0])
p->s[0]->rev^=1;
if(p->s[1])
p->s[1]->rev^=1;
p->rev=0;
}
void mt(tree *&p)
{
p->sum=1;
if(p->s[0])
p->sum+=p->s[0]->sum;
if(p->s[1])
p->sum+=p->