上来没读清题,写了个双向链表一阵模拟,对着空气用力了一小时,读清题后就gg了。
搜索题解,splay,wtf??我不会啊!!嗯?rope,好东西,先码一下。
这是什么东西,其实就是一个可以比较高效的地实现区间转换的东西
rope的基本操作
#include <ext/rope>
using namespace __gnu_cxx;
//以上两个东西是使用rope需要用的
//1.声明
rope<int>t;
//2.初始化
t.clear();
//3.操作
t.push_back(x);//在末尾添加x(元素)
t.insert(pos,x);//在pos位置(pos=0...t.size()-1)插入x(元素/rope)
t.copy(pos,x,to);//把rope从pos开始的x个元素,覆盖到指针node* to中
t.replace(pos,x,y);//从pos开始的x个换成y(元素/rope)
t.erase(pos,x);//从pos开始删除x个
t.substr(pos,x);//提取pos开始x个
t.at(pos)/t[pos];//访问pos位置元素
下面是代码
#include <bits/stdc++.h>
#include <ext/rope>
using namespace std;
using namespace __gnu_cxx;
rope <int> s, tmp;
int main(){
int n, m;
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i ++)
s. push_back(i);
int l, r;
while(m --){
scanf("%d %d", &l, &r);
tmp = s. substr(l - 1, r);
s. erase(l - 1, r);
s = tmp + s;
}
for(int i = 0; i < n; i ++){
printf("%d%c", s[i], i == n - 1 ? '\n' : ' ');
}
return 0;
}
splay的代码,emmm,待我学习一下再来补上233
早起码了一早上,感觉自己要上天~
只要注意到区间前提的操作可以通过三次区间翻转实现就可以套splay了
#include <bits/stdc++.h>
#define Key_value ch[ch[root][1]][0]
using namespace std;
const int N = 500500;
const int inf = 0x3f3f3f3f;
int pre[N], ch[N][2], key[N], size[N];
int sum[N], rev[N], same[N];
int lx[N], rx[N], mx[N];
int root, tot1;
int s[N], tot2;
int a[N];
int n, q;
//debug 部分
void Treavel(int x){
if(x){
Treavel(ch[x][0]);
printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d key=%2d, size= %2d, sum=%2d,rev=%2d same=%2d lx=%2d rx=%2d mx=%2d\n",x,ch[x][0],ch[x][1],pre[x],key[x],size[x],sum[x],rev[x],same[x],lx[x],rx[x],mx[x]);
Treavel(ch[x][1]);
}
}
void debug(){
printf("root%d\n", root);
Treavel(root);
}
void NewNode(int &r, int father, int k){
if(tot2)
r = s[tot2 --];
else
r = ++ tot1;
pre[r] = father;
ch[r][0] = ch[r][1] = 0;
key[r] = k;
sum[r] = k;
rev[r] = same[r] = 0;
lx[r] = rx[r] = mx[r] = k;
size[r] = 1;
}
void Updata_Same(int r, int v){
if(! r)
return ;
key[r] = v;
sum[r] = v * size[r];
lx[r] = rx[r] = mx[r] = max(v, v * size[r]);
same[r] = 1;
}
void Updata_Rev(int r){
if(! r)
return ;
swap(ch[r][0], ch[r][1]);
swap(lx[r], rx[r]);
rev[r] ^= 1;
}
void Push_Up(int r){
int lson = ch[r][0], rson = ch[r][1];
size[r] = size[lson] + size[rson] + 1;
sum[r] = sum[lson] + sum[rson] + key[r];
lx[r] = max(lx[lson], sum[lson] + key[r] + max(0, lx[rson]));
rx[r] = max(rx[rson], sum[rson] + key[r] + max(0, rx[lson]));
mx[r] = max(0, rx[lson] + key[r] + max(0, lx[rson]));
mx[r] = max(mx[r], max(mx[lson], mx[rson]));
}
void Push_Down(int r){
if(same[r]){
Updata_Same(ch[r][0], key[r]);
Updata_Same(ch[r][1], key[r]);
same[r] = 0;
}
if(rev[r]){
Updata_Rev(ch[r][0]);
Updata_Rev(ch[r][1]);
rev[r] = 0;
}
}
void Build(int &x, int l, int r, int father){
if(l > r)
return ;
int mid = (l + r) / 2;
NewNode(x, father, a[mid]);
Build(ch[x][0], l, mid - 1, x);
Build(ch[x][1], mid + 1, r, x);
Push_Up(x);
}
void Init(){
root = tot1 = tot2 = 0;
ch[root][0] = ch[root][1] = pre[root] = size[root] = same[root] = rev[root] = sum[root] = key[root] = 0;
lx[root] = rx[root] = mx[root] = -inf;
NewNode(root, 0, -1);
NewNode(ch[root][1], root, -1);
for(int i = 0; i < n; i ++)
a[i] = i + 1;
Build(Key_value, 0, n - 1, ch[root][1]);
Push_Up(ch[root][1]);
Push_Up(root);
}
void Rotate(int x, int kind){
int y = pre[x];
Push_Down(y);
Push_Down(x);
ch[y][! kind] = ch[x][kind];
pre[ch[x][kind]] = y;
if(pre[y])
ch[pre[y]][ch[pre[y]][1] == y] = x;
pre[x] = pre[y];
ch[x][kind] = y;
pre[y] = x;
Push_Up(y);
}
void Splay(int r, int goal){
Push_Down(r);
while(pre[r] != goal){
if(pre[pre[r]] == goal){
Push_Down(pre[r]);
Push_Down(r);
Rotate(r, ch[pre[r]][0] == r);
}
else{
Push_Down(pre[pre[r]]);
Push_Down(pre[r]);
Push_Down(r);
int y = pre[r];
int kind = ch[pre[y]][0] == y;
if(ch[y][kind] == r){
Rotate(r, ! kind);
Rotate(r, kind);
}
else{
Rotate(y, kind);
Rotate(r, kind);
}
}
}
Push_Up(r);
if(goal == 0)
root = r;
}
int Get_Kth(int r, int k){
Push_Down(r);
int t = size[ch[r][0]] + 1;
if(t == k)
return r;
if(t > k)
return Get_Kth(ch[r][0], k);
else
return Get_Kth(ch[r][1], k - t);
}
//在第POS个数后插入tot个数
void Insert(int pos, int tot){
for(int i = 0; i < tot; i ++)
scanf("%d", &a[i]);
Splay(Get_Kth(root, pos + 1), 0);
Splay(Get_Kth(root, pos + 2), root);
Build(Key_value, 0, tot - 1, ch[root][1]);
Push_Up(ch[root][1]);
Push_Up(root);
}
void erase(int r){
if(! r)
return ;
s[++ tot2] = r;
erase(ch[r][0]);
erase(ch[r][1]);
}
//从第pos个数开始连续删除tot个数
void Delete(int pos, int tot){
Splay(Get_Kth(root, pos), 0);
Splay(Get_Kth(root, pos + tot + 1), root);
erase(Key_value);
pre[Key_value] = 0;
Push_Up(ch[root][1]);
Push_Up(root);
}
//从第pos个数开始连续的tot个数修改为c
void Make_Same(int pos, int tot, int c){
Splay(Get_Kth(root, pos), 0);
Splay(Get_Kth(root, pos + tot + 1), root);
Updata_Same(Key_value, c);
Push_Up(ch[root][1]);
Push_Up(root);
}
//反转
void Reverse(int pos, int tot){
Splay(Get_Kth(root, pos), 0);
Splay(Get_Kth(root, pos + tot + 1), root);
Updata_Rev(Key_value);
Push_Up(ch[root][1]);
Push_Up(root);
}
//求和
int Get_Sum(int pos, int tot){
Splay(Get_Kth(root, pos), 0);
Splay(Get_Kth(root, pos + tot + 1), root);
return sum[Key_value];
}
//得到最大和
int Get_MaxSum(int pos, int tot){
Splay(Get_Kth(root, pos), 0);
Splay(Get_Kth(root, pos + tot + 1), root);
return mx[Key_value];
}
int cnt;
void Inorder(int r){
if(! r)
return ;
Push_Down(r);
Inorder(ch[r][0]);
if(key[r] != -1)
printf("%d%c", key[r], ++cnt == n ? '\n' : ' ');
Inorder(ch[r][1]);
}
int main(){
while(scanf("%d %d", &n, &q) == 2){
Init();
int x, y;
while(q --){
scanf("%d %d", &x, &y);
Reverse(1, y + x - 1);
Reverse(1, y);
Reverse(y + 1, x - 1);
}
cnt = 0;
Inorder(root);
}
return 0;
}