POJ 3580 SuperMemo (splay tree)
SuperMemo
Description Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to play a memorizing game. At first, the host tells the participant a sequence of numbers, {A1, A2, ... An}. Then the host performs a series of operations and queries on the sequence which consists:
To make the show more interesting, the participant is granted a chance to turn to someone else that means when Jackson feels difficult in answering a query he may call you for help. You task is to watch the TV show and write a program giving the correct answer to each query in order to assist Jackson whenever he calls. Input The first line contains n (n ≤ 100000). The following n lines describe the sequence. Then follows M (M ≤ 100000), the numbers of operations and queries. The following M lines describe the operations and queries. Output For each "MIN" query, output the correct answer. Sample Input 5 Sample Output 5 Source POJ Founder Monthly Contest – 2008.04.13, Yao Jinyu
|
/* ***********************************************
Author :kuangbin
Created Time :2013/8/28 19:39:45
File Name :F:\2013ACM练习\专题学习\splay_tree_2\POJ3580.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
/*
* 给定一个数列:a1,a2,.... an
* 进行以下6种操作:
* ADD x y D : 给第x个数到第y个数加D
* REVERSE x y : 反转[x,y]
* REVOVLE x y T : 对[x,y]区间的数循环右移T次
* (先把T对长度取模,然后相当于把[y-T+1,y]放到[x,y-T] 的前面)
* INSERT x P : 在第x个数后面插入P
* DELETE x : 删除第x个数
* MIN x y : 查询[x,y]之间的最小的数
*/
#define Key_value ch[ch[root][1]][0]
const int MAXN = ;
const int INF = 0x3f3f3f3f;
int pre[MAXN],ch[MAXN][],root,tot1,size[MAXN];
int key[MAXN],rev[MAXN],m[MAXN],add[MAXN];
int s[MAXN],tot2;
int a[MAXN];
int n;
void NewNode(int &r,int father,int k)
{
if(tot2) r = s[tot2--];
else r = ++tot1;
pre[r] = father;
ch[r][] = ch[r][] = ;
key[r] = k;
m[r] = k;
rev[r] = add[r] = ;
size[r] = ;
}
void Update_Rev(int r)
{
if(!r)return;
swap(ch[r][],ch[r][]);
rev[r] ^= ;
}
void Update_Add(int r,int D)
{
if(!r)return;
m[r] += D;
key[r] += D;
add[r] += D;
}
void push_up(int r)
{
size[r] = size[ch[r][]] + size[ch[r][]] + ;
m[r] = min(key[r],min(m[ch[r][]],m[ch[r][]]));
}
void push_down(int r)
{
if(rev[r])
{
Update_Rev(ch[r][]);
Update_Rev(ch[r][]);
rev[r] = ;
}
if(add[r])
{
Update_Add(ch[r][],add[r]);
Update_Add(ch[r][],add[r]);
add[r] = ;
}
}
void Build(int &x,int l,int r,int father)
{
if(l > r)return;
int mid = (l+ r)/;
NewNode(x,father,a[mid]);
Build(ch[x][],l,mid-,x);
Build(ch[x][],mid+,r,x);
push_up(x);
}
void Init()
{
root = tot1 = tot2 = ;
ch[root][] = ch[root][] = pre[root] = ;
rev[root] = add[root] = ;
m[root] = INF;
size[root] = ;
NewNode(root,,-);
NewNode(ch[root][],root,-);
for(int i = ;i < n;i++)
scanf("%d",&a[i]);
Build(Key_value,,n-,ch[root][]);
push_up(ch[root][]);
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]][]==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]][]==r);
}
else
{
push_down(pre[pre[r]]);
push_down(pre[r]);
push_down(r);
int y = pre[r];
int kind = ch[pre[y]][]==y;
if(ch[y][kind] == r)
{
Rotate(r,!kind);
Rotate(r,kind);
}
else
{
Rotate(y,kind);
Rotate(r,kind);
}
}
}
push_up(r);
if(goal == ) root = r;
} int Get_kth(int r,int k)
{
push_down(r);
int t = size[ch[r][]] + ;
if(t == k) return r;
if(t > k) return Get_kth(ch[r][],k);
else return Get_kth(ch[r][],k-t);
} void ADD(int x,int y,int D)
{
Splay(Get_kth(root,x),);
Splay(Get_kth(root,y+),root);
Update_Add(Key_value,D);
push_up(ch[root][]);
push_up(root);
}
void Reverse(int x,int y)
{
Splay(Get_kth(root,x),);
Splay(Get_kth(root,y+),root);
Update_Rev(Key_value);
push_up(ch[root][]);
push_up(root);
}
void REVOLVE(int x,int y,int T)
{
int len = y - x + ;
T = ( T%len + len )%len;
Splay(Get_kth(root,y-T+),);
Splay(Get_kth(root,y+),root);
int tmp = Key_value;
Key_value = ;
push_up(ch[root][]);
push_up(root);
Splay(Get_kth(root,x),);
Splay(Get_kth(root,x+),root);
Key_value = tmp;
pre[tmp] = ch[root][];
push_up(ch[root][]);
push_up(root);
}
void INSERT(int x,int P)
{
Splay(Get_kth(root,x+),);
Splay(Get_kth(root,x+),root);
NewNode(Key_value,ch[root][],P);
push_up(ch[root][]);
push_up(root);
}
void erase(int r)
{
if(!r)return;
s[++tot2] = r;
erase(ch[r][]);
erase(ch[r][]);
}
void DELETE(int x)
{
Splay(Get_kth(root,x),);
Splay(Get_kth(root,x+),root);
erase(Key_value);
pre[Key_value] = ;
Key_value = ;
push_up(ch[root][]);
push_up(root);
}
int MIN(int x,int y)
{
Splay(Get_kth(root,x),);
Splay(Get_kth(root,y+),root);
return m[Key_value];
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d",&n) == )
{
Init();
int x,y,z;
char op[];
int q;
scanf("%d",&q);
while(q--)
{
scanf("%s",op);
if(strcmp(op,"ADD") == )
{
scanf("%d%d%d",&x,&y,&z);
ADD(x,y,z);
}
else if(strcmp(op,"REVERSE") == )
{
scanf("%d%d",&x,&y);
Reverse(x,y);
}
else if(strcmp(op,"REVOLVE") == )
{
scanf("%d%d%d",&x,&y,&z);
REVOLVE(x,y,z);
}
else if(strcmp(op,"INSERT") == )
{
scanf("%d%d",&x,&y);
INSERT(x,y);
}
else if(strcmp(op,"DELETE") == )
{
scanf("%d",&x);
DELETE(x);
}
else if(strcmp(op,"MIN") == )
{
scanf("%d%d",&x,&y);
printf("%d\n",MIN(x,y));
}
}
}
return ;
}
POJ 3580 SuperMemo (splay tree)的更多相关文章
- 伸展树(Splay Tree)进阶 - 从原理到实现
目录 1 简介 2 基础操作 2.1 旋转 2.2 伸展操作 3 常规操作 3.1 插入操作 3.2 删除操作 3.3 查找操作 3.4 查找某数的排名.查找某排名的数 3.4.1 查找某数的排名 3 ...
- 数据结构(二) --- 伸展树(Splay Tree)
文章图片和代码来自邓俊辉老师课件 概述 伸展树(Splay Tree),也叫分裂树,是一种二叉排序树,它能在O(log n)内完成插入.查找和删除操作.它由丹尼尔·斯立特Daniel Sleator ...
- 纸上谈兵:伸展树(splay tree)
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我们讨论过,树的搜索效率与树的深度有关.二叉搜索树的深度可能为n,这种情况下,每次 ...
- HDU 1890 Robotic Sort (splay tree)
Robotic Sort Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- 平衡树之伸展树(Splay Tree)题目整理
目录 前言 练习1 BZOJ 3224 普通平衡树 练习2 BZOJ 3223 文艺平衡树 练习3 BZOJ 1588 [HNOI2002]营业额统计 练习4 BZOJ 1208 [HNOI2004] ...
- 伸展树(splay tree)
伸展树的设计思路,鉴于数据访问的局部性(28原则)在实际应用中普遍存在,将按照"最常用者优先"的启发策略.尽管在最坏情况下其单次操作需要 O(n) 时间,但分摊而言仍然 O(log ...
- BZOJ 1269: [AHOI2006]文本编辑器editor (splay tree)
1269: [AHOI2006]文本编辑器editor Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1213 Solved: 454[Submit ...
- HDU 3436 Queue-jumpers (splay tree)
Queue-jumpers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- HDU 1890--Robotic Sort(Splay Tree)
题意:每次找出第i大的数的位置p输出,然后将i~p之间的数反转. 题解:每次把要的区间转成一棵子树,然后更新.因为每次将第i小的数转到了了i,所以k次操作后,可知前k个数一定是最小的那k个数,所以以后 ...
随机推荐
- js实现数据视图双向绑定原理
这个方法了不起啊..vue.js和avalon.js 都是通过它实现双向绑定的..而且Object.observe也被草案发起人撤回了..所以defineProperty更有必要了解一下了几行代码看他 ...
- java基础49 IO流技术(对象输入流/对象输出流)
1.对象输入输出流 对象注意作用是用于写对象信息与读取对象信息 1.对象输出流:ObjectOutputStream 2.对象输入流:ObjectInputStream 2.对象输入输出流的步骤 ...
- linux内核之accept实现
用户态对accept的标准用法: if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size) ...
- ubuntu和windows双系统启动顺序的修改
ubuntu和windows双系统启动顺序的修改 说到启动就不得不说GRUB,Linux下大名鼎鼎的启动管理工具(曾经的LILO已经风光不再),当然现在已经是GRUB2了,GRUB2和GRUB最重要的 ...
- Java事务管理之Hibernate
环境与版本 Hibernate 版本:Hibernate 4.2.2 (下载后的文件名为hibernate-release-4.2.2.Final.zip,解压目录hibernate-release- ...
- Python 安装 pytesser 处理验证码出现的问题
今天这个问题困扰了我好久,开始直接用 pip install pytesseract 安装了 pytesseract 然后出现了如下错误 Traceback (most recent call las ...
- How to tell your iPhone application that location services are required | The Agile Warrior
div{padding-bottom:10px}.b_vPanel>div:last-child{padding:0}.banner a{color:#1020d0} --> Below ...
- c 语言文本文件判断是否到达结尾的问题
在c语言中,判断文件结尾有两种方法,第一种是使用feof()函数,feof(fp)用于测试fp所指向的文件的当前状态是否为“文件结束”.如果是,函数则返回的是非0值(真),否则为0(假),要注意的是, ...
- 一步一步学习IdentityServer3 (5)
这篇文章介绍下数据持久化问题,官方例子可能都是缓存数据 Client User Scope 下面介绍下怎么使用数据库持久化 这里需要导入nuget包 :IdentityServer3.EntityF ...
- shuffle过程分析
shuffle的过程分析 shuffle阶段其实就是之前<MapReduce的原理及执行过程>中的步骤2.1.多个map任务的输出,按照不同的分区,通过网络copy到不同的reduce节点 ...