题意: 给你n 张卡牌分别为1到n 1 在顶 n在尾,每次给你l len 你要将 l 处一下的len 个(包括l) 挪到顶上。问你m次操作后的序列。
代码:
#include<bits/stdc++.h>
using namespace std;
const int inf =0x3f3f3f3f;
struct Node
{
Node *ch[2];
int s,v;
int cmp(int k)
{
int d=k-ch[0]->s;
if(d==1) return -1;
else return d<=0?0:1;
}
void maintain()
{
s=ch[0]->s+ch[1]->s+1;
}
};
Node *null =new Node();
void rotate(Node* &o,int d)
{
Node *k=o->ch[d^1];
o->ch[d^1]=k->ch[d];
k->ch[d]=o;
o->maintain();
k->maintain();
o=k;
}
void splay(Node* &o,int k)
{
int d=o->cmp(k);
if(d==1) k-=(o->ch[0]->s+1);
if(d!=-1){
Node *p=o->ch[d];
int d2=p->cmp(k);
int k2=(d2==0?k:k-1-p->ch[0]->s);
if(d2!=-1){
splay(p->ch[d2],k2);
if(d==d2) rotate(o,d^1);
else rotate(o->ch[d],d);
}
rotate(o,d^1);
}
}
Node* merge(Node *left,Node *right)
{
splay(left,left->s);
left->ch[1]=right;
left->maintain();
return left;
}
void split(Node* o,int k,Node* &left,Node* &right)
{
splay(o,k);
left=o;
right=o->ch[1];
o->ch[1]=null;
left->maintain();
}
const int maxn=2e5+5;
vector< int >ans;
struct SplaySequence
{
int n;
int num[maxn];
Node seq[maxn];
Node *root;
Node* build(int sz)
{
if(sz==0) return null;
Node *L=build(sz/2);
Node *o=&seq[n];
o->v=num[n++];
o->ch[0]=L;
o->ch[1]=build(sz-sz/2-1);
o->s=0;
o->maintain();
return o;
}
void init(int sz)
{
n=0;
null->s=0;
//cout<<"lala"<<" "<<sz<<endl;
root=build(sz);
}
};
void print(Node *o)
{
if(o!=null){
print(o->ch[1]);
ans.push_back(o->v);
print(o->ch[0]);
}
}
void debug(Node* o)
{
if(o!=null){
debug(o->ch[0]);
printf("*** %d",o->v);
debug(o->ch[1]);
}
}
SplaySequence ss;
int n,m;
int main()
{
scanf("%d %d",&n,&m);
ss.num[0]=inf;
for(int i=1;i<=n;i++){
ss.num[i]=n+1-i;
}
ss.init(n+1);
Node *o,*left,*right,*mid;
int l,r;
while(m--)
{
scanf("%d %d",&l,&r);
r=l+r-1;
l=n+2-l; r=n+2-r;
swap(l,r);
//cout<<"l "<<l<<" r "<<r<<endl;
split(ss.root,l-1,left,o);
split(o,r-l+1,mid,right);
ss.root=merge( merge(left,right),mid );
}
print(ss.root);
printf("%d",ans[0]);
for(int i=1;i<ans.size()-1;i++){
printf(" %d",ans[i]);
}
cout<<endl;
return 0;
}
rope
#include<bits/stdc++.h>
using namespace std;
#include <ext/rope>
using namespace __gnu_cxx;
rope<int>T;
int main()
{
int n, m, x, y;
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++)
T.push_back(i);
while(m--){
scanf("%d%d", &x, &y);
//cout<<x-1<<" "<<y<<endl;
T.insert(0, T.substr(x-1,y));
//cout<<y+x-1<<" "<<y<<endl;
T.erase(y+x-1,y);
}
for(int i=0; i<n; i++)
printf("%d%c", T[i], i!=n-1?' ':'\n');
}
rope 基本用法
#include <ext/rope>
using namespace __gnu_cxx;
int a[1000];
rope<int> x;
rope<int> x(a,a + n);
rope<int> a(x);
x->at(10);
x[10];
x->push_back(x) // 在末尾添加x
x->insert(pos,x) // 在pos插入x
x->erase(pos,x) // 从pos开始删除x个
x->replace(pos,x) // 从pos开始换成x
x->substr(pos,x) // 提取pos开始x个