博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 3487 Play with Chain
阅读量:6540 次
发布时间:2019-06-24

本文共 3713 字,大约阅读时间需要 12 分钟。

HDU_3487

    拿这个题目练了一下splay的区间的切割,也就是删除、移动、添加一个连续的区间。

#include
#include
#define MAXD 300010 int N, M, T, node, size[MAXD], rev[MAXD], left[MAXD], right[MAXD], pre[MAXD], key[MAXD], ans[MAXD], P; void newnode(int &cur, int k) {
cur = ++ node; key[cur] = k; size[cur] = 1; rev[cur] = 0; left[cur] = right[cur] = 0; } void update(int cur) {
size[cur] = size[left[cur]] + size[right[cur]] + 1; } void pushdown(int cur) {
if(rev[cur]) {
int ls = left[cur], rs = right[cur]; rev[ls] = (rev[ls] + 1) & 1, rev[rs] = (rev[rs] + 1) & 1; left[cur] = rs, right[cur] = ls; rev[cur] = 0; } } void build(int &cur, int x, int y, int p) {
int mid = (x + y) / 2; newnode(cur, mid); pre[cur] = p; if(x == y) return ; if(x < mid) build(left[cur], x, mid - 1, cur); if(mid < y) build(right[cur], mid + 1, y, cur); update(cur); } void init() {
T = node = size[0] = left[0] = right[0] = 0; newnode(T, 0), newnode(right[T], N + 1); size[T] = 2, pre[T] = 0, pre[right[T]] = T; build(left[right[T]], 1, N, right[T]); update(right[T]), update(T); } void leftrotate(int x) {
int y = right[x], p = pre[x]; right[x] = left[y]; if(right[x]) pre[right[x]] = x; left[y] = x; pre[x] = y; pre[y] = p; if(p == 0) T = y; else right[p] == x ? right[p] = y : left[p] = y; update(x); } void rightrotate(int x) {
int y = left[x], p = pre[x]; left[x] = right[y]; if(left[x]) pre[left[x]] = x; right[y] = x; pre[x] = y; pre[y] = p; if(p == 0) T = y; else right[p] == x ? right[p] = y : left[p] = y; update(x); } void splay(int x, int goal) {
int y, z; for(;;) {
if((y = pre[x]) == goal) break; if((z = pre[y]) == goal) right[y] == x ? leftrotate(y) : rightrotate(y); else {
if(right[z] == y) {
if(right[y] == x) leftrotate(z), leftrotate(y); else rightrotate(y), leftrotate(z); } else {
if(left[y] == x) rightrotate(z), rightrotate(y); else leftrotate(y), rightrotate(z); } } } update(x); } void rotateto(int k, int goal) {
int i = T; for(;;) {
pushdown(i); if(k == size[left[i]] + 1) break; if(k <= size[left[i]]) i = left[i]; else k -= size[left[i]] + 1, i = right[i]; } splay(i, goal); } void cut(int x, int y, int z) {
int k, t; rotateto(x, 0), rotateto(y + 2, T); t = left[right[T]]; left[right[T]] = 0; update(right[T]), update(T); rotateto(z + 1, 0), rotateto(z + 2, T); pre[t] = right[T]; left[right[T]] = t; update(right[T]), update(T); } void flip(int x, int y) {
int k; rotateto(x, 0), rotateto(y + 2, T); k = left[right[T]]; rev[k] = (rev[k] + 1) & 1; } void solve() {
int i, x, y, z; char b[10]; for(i = 0; i < M; i ++) {
scanf("%s", b); if(b[0] == 'C') {
scanf("%d%d%d", &x, &y, &z); cut(x, y, z); } else {
scanf("%d%d", &x, &y); flip(x, y); } } } void dfs(int cur) {
pushdown(cur); if(left[cur]) dfs(left[cur]); ans[P ++] = key[cur]; if(right[cur]) dfs(right[cur]); } void printresult() {
int i; P = 0; dfs(T); printf("%d", ans[1]); for(i = 2; i < P - 1; i ++) printf(" %d", ans[i]); printf("\n"); } int main() {
while(scanf("%d%d", &N, &M) == 2) {
if(N < 0 && M < 0) break; init(); solve(); printresult(); } return 0; }

转载地址:http://musdo.baihongyu.com/

你可能感兴趣的文章
wcf客户端终结点样本集合
查看>>
Java递归算法——阶乘
查看>>
ios开发应用内实现多语言自由切换
查看>>
Multi-voltage和power gating的实现
查看>>
JavaScript面向对象 ~ 原型和继承(1)
查看>>
ubuntu下安装nginx时依赖库zlib,pcre,openssl安装方法
查看>>
spring cloud微服务分布式云架构--hystrix的使用
查看>>
linux tail
查看>>
解决Mac启动Eclipse Memory Analyzer报错问题
查看>>
jquery的$().each,$.each的区别
查看>>
自己写的进度条###
查看>>
windows磁盘扩容(动态磁盘)
查看>>
在jsp页面中添加富文本编译器(ueditor)+ 图片上传功能
查看>>
fedora12下安装oracle11客户端
查看>>
实现批量添加20个用户,用户名为user1-50,密码为user后面跟5个随机字符
查看>>
Net命令详解
查看>>
CentOS linux 高可用集群之heartbeat
查看>>
用bat更改hosts文件批处理
查看>>
Logwatch日志分析工具
查看>>
docker 基本操作Ⅱ(关于镜像操作)
查看>>