链接:

https://www.nowcoder.com/acm/contest/141/C

题意:

给出一个n个元素的序列(1,2,...,n)和m个操作(1≤n,m≤1e5),
每个操作给出两个数p和s(1≤pi≤n,1≤si≤n-pi+1),表示把序列中从p开始的s个数移到最前面,
例如序列[1,2,3,4,5]在p=2,s=3时变成序列[2,3,4,1,5],输出最后的序列。

分析:

对于每个操作,直接把序列拆成三个部分,再重新拼接一下就行。
可以用Splay或rope来快速完成这个操作。

代码:

Splay版

 #include <cstdio>

 /// 元素编号从1开始,使用前要初始化(init)
template<typename type> // 元素类型
class SplaySequence {
public:
struct Node {
Node *ch[]; // 左右子树
int s; // 结点数
type v; // 值
bool flip; // 反转标记
int cmp(int k) const {
int d = k - ch[]->s;
if(d == ) return -;
return d <= ? : ;
}
void maintain() {
s = ch[]->s + ch[]->s + ;
}
void pushdown() {
if(!flip) return;
flip = false;
Node* t = ch[]; ch[] = ch[]; ch[] = t;
ch[]->flip ^= ;
ch[]->flip ^= ;
}
};
Node* root; // 根结点
// 将序列分裂成s[1...k]和s[k+1...o->s],分别放于left和right
void split(Node* o, int k, Node* &left, Node* &right) {
if(k <= ) {
left = null;
right = o;
return;
}
splay(o, k);
left = o;
right = o->ch[];
o->ch[] = null;
left->maintain();
}
// 合并left和right。
Node* merge(Node* left, Node* right) {
if(left == null) return right;
splay(left, left->s);
left->ch[] = right;
left->maintain();
return left;
}
// 在第k个元素之后插入v
void insert(int k, type v) {
Node *left, *right, *mid = newNode();
mid->ch[] = mid->ch[] = null;
mid->s = ;
mid->v = v;
mid->flip = false;
split(root, k, left, right);
root = merge(merge(left, mid), right);
}
// 删除第k个元素
void erase(int k) {
Node *left, *right, *mid, *o;
split(root, k-, left, o);
split(o, , mid, right);
root = merge(left, right);
delNode(mid);
}
// 将第L...R个元素反转
void reverse(int L, int R) {
Node *left, *right, *mid, *o;
split(root, L-, left, o);
split(o, R-L+, mid, right);
mid->flip ^= ;
root = merge(merge(left, mid), right);
}
// 返回第k个元素
Node* kth(int k) {
Node* o = root;
while(o != null) {
int d = o->cmp(k);
if(d == -) return o;
if(d == ) k -= o->ch[]->s + ;
o = o->ch[d];
}
return null;
}
// 读取第k个元素
type operator[](int k) {
return kth(k)->v;
}
// 返回元素个数
int size() {
return root->s;
}
// 初始化、清空序列
void init() {
for(int i = ; i < MAXS; i++) stk[i] = &mem[i];
top = MAXS - ;
null = newNode();
null->s = ;
root = null;
}
// 中序遍历输出整个序列
void print(Node* o) {
if(o == null) return;
o->pushdown();
print(o->ch[]);
printf("%d ", o->v);
print(o->ch[]);
}
private:
static const int MAXS = 1e6 + ; // 最大结点数
Node* null;
int top;
Node* stk[MAXS];
Node mem[MAXS];
void rotate(Node* &o, int d) {
Node* k = o->ch[d^];
o->ch[d^] = k->ch[d];
k->ch[d] = o;
o->maintain();
k->maintain();
o = k;
}
void splay(Node* &o, int k) {
o->pushdown();
int d = o->cmp(k);
if(d == -) return;
if(d == ) k -= o->ch[]->s + ;
Node* p = o->ch[d];
p->pushdown();
int d2 = p->cmp(k);
int k2 = (d2 == ? k : k - p->ch[]->s - );
if(d2 != -) {
splay(p->ch[d2], k2);
if(d == d2) rotate(o, d^);
else rotate(o->ch[d], d);
}
rotate(o, d^);
}
Node* newNode() {
return stk[top--];
}
void delNode(Node* o) {
stk[++top] = o;
}
}; SplaySequence<int> ss; int main() {
int n, m;
scanf("%d%d", &n, &m);
ss.init();
for(int i = ; i <= n; i++) ss.insert(ss.size(), i);
for(int p, s, i = ; i < m; i++) {
scanf("%d%d", &p, &s);
SplaySequence<int>::Node *left, *mid, *right, *o;
ss.split(ss.root, p-, left, o);
ss.split(o, s, mid, right);
ss.root = ss.merge(ss.merge(mid, left), right);
}
ss.print(ss.root);
return ;
}

rope版

 #include <cstdio>
#include <ext/rope>
using namespace __gnu_cxx; rope<int> r; int main() {
int n, m;
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++) r.push_back(i);
for(int p, s, i = ; i < m; i++) {
scanf("%d%d", &p, &s);
p--;
r = r.substr(p, s) + r.substr(, p) + r.substr(p+s, n-p-s);
}
for(int i = ; i < n; i++) printf("%d ", r[i]);
return ;
} /*
r.push_back(x); // 在末尾添加x
r.insert(pos, x); // 在pos插入x
r.erase(pos, x); // 从pos开始删除x个
r.copy(pos, len, x); // 从pos开始到pos+len为止用x代替
r.replace(pos, x); // 从pos开始换成x
r.substr(pos, x); // 提取pos开始x个
r.at(x) / [x]; // 访问第x个元素
时间复杂度为n*(n^0.5)
*/

牛客网多校训练第三场 C - Shuffle Cards(Splay / rope)的更多相关文章

  1. 牛客网多校训练第三场 A - PACM Team(01背包变形 + 记录方案)

    链接: https://www.nowcoder.com/acm/contest/141/A 题意: 有n(1≤n≤36)个物品,每个物品有四种代价pi,ai,ci,mi,价值为gi(0≤pi,ai, ...

  2. 牛客网多校训练第四场C sequence

    (牛客场场有笛卡尔树,场场都不会用笛卡尔树...自闭,补题心得) 题目链接:https://ac.nowcoder.com/acm/contest/884/C 题意:给出两个序列a,b,求max{mi ...

  3. 牛客网2018暑期训练 第三场 a题

    #include <bits/stdc++.h> using namespace std; vector<int> path; ; short dp[maxn][maxn][m ...

  4. 牛客网多校训练第八场A All one Matrix

    题目链接:https://ac.nowcoder.com/acm/contest/888/A 题意:求出有多少个不被包含的全1子矩阵 解题思路:首先对列做处理,维护每个位置向上1的个数,然后我们从最后 ...

  5. 牛客网多校训练第二场D Kth Minimum Clique

    链接:https://ac.nowcoder.com/acm/contest/882/D来源:牛客网 Given a vertex-weighted graph with N vertices, fi ...

  6. 牛客网多校赛第9场 E-Music Game【概率期望】【逆元】

    链接:https://www.nowcoder.com/acm/contest/147/E 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524 ...

  7. 牛客网多校赛第七场J--Sudoku Subrectangle

    链接:https://www.nowcoder.com/acm/contest/145/J 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言6553 ...

  8. 牛客网多校赛第七场--C Bit Compression【位运算】【暴力】

    链接:https://www.nowcoder.com/acm/contest/145/C 来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言524 ...

  9. 牛客网多校赛第七场A--Minimum Cost Perfect Matching【位运算】【规律】

    链接:https://www.nowcoder.com/acm/contest/145/A 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524 ...

随机推荐

  1. Magento 2中文手册教程 - Magento 2 安装流程图

    下图提供了安装Magento 2的安装流程概述: 设置你的服务器环境. 安装magento 2 必备软件, PHP, Apache, MySQL. 系统需求详细信息: 2.1.x 系统需求 获得mag ...

  2. SQL练习(一)

    查找今天过生日的同学 这里表中已经存储了生日,所以思路是取出date_birth去今天的日期相比较 SELECT NAME,date_birth FROM org_mhi_studentfiles W ...

  3. zookeeper【4】master选举

    考虑7*24小时向外提供服务的系统,不能有单点故障,于是我们使用集群,采用的是Master+Slave.集群中有一台主机和多台备机,由主机向外提 供服务,备机监听主机状态,一旦主机宕机,备机必需迅速接 ...

  4. Heka 的编译

    Heka是Mozilla开源的,基于Go语言实现的,插件式log收集和分析系统. 已经编译好的 release 版本可以在下面地址下载: https://github.com/mozilla-serv ...

  5. go install runtime/cgo: open /usr/local/go/pkg/darwin_amd64/runtime/cgo.a: permission denied

    在做更新时,收到下面提示: go get  github.com/astaxie/beego go install runtime/cgo: open /usr/local/go/pkg/darwin ...

  6. Java并发编程:volatile关键字解析(学习总结-海子)

    博文地址:Java并发编程:volatile关键字解析

  7. float、display和流

    一.css的元素有很深的道理和它存在的意义 块元素:默认元素的上下左右会有间隔(即使设置margin.padding为0也一样).如果想0间隔,考虑float. float:会使元素自动生成一个块级框 ...

  8. sql server query to get the list of column name in a table

    --SQL Server 2005, 2008 or 2012: SELECT * FROM information_schema.tables --SQL Server 2000: SELECT * ...

  9. Scrapy框架的使用

    Scrapy框架的安装 pip install pywin32 下载 Twisted 包       pip install Twisted包的路径 pip insatll scrapy Scrapy ...

  10. window onload || jquery $()

    1.window 的 onload 机制只指定一个函数,且在页面DOM及静态资源加载完之后执行: window.onload = function(){ alert(); } 2.$(document ...