POJ 3580 Splay

G - SuperMemo

Time Limit:5000MS     Memory Limit:65536KB     64bit IO Format:%I64d
& %I64u

Submit Status Practice POJ
3580

Appoint description: 
System Crawler  (2014-11-27)

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, {A1A2, ... An}.
Then the host performs a series of operations and queries on the sequence which consists:

  1. ADD x y D: Add D to each number in sub-sequence {Ax ... Ay}. For example, performing "ADD 2 4 1" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5, 5}
  2. REVERSE x y: reverse the sub-sequence {Ax ... Ay}. For example, performing "REVERSE 2 4" on {1, 2, 3, 4, 5} results in {1, 4, 3, 2, 5}
  3. REVOLVE x y T: rotate sub-sequence {Ax ... AyT times. For example, performing "REVOLVE 2 4 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 2, 5}
  4. INSERT x P: insert P after Ax. For example, performing "INSERT 2 4" on {1, 2, 3, 4, 5} results in {1, 2, 4, 3, 4, 5}
  5. DELETE x: delete Ax. For example, performing "DELETE 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5}
  6. MIN x y: query the participant what is the minimum number in sub-sequence {Ax ... Ay}. For example, the correct answer to "MIN 2 4" on {1, 2, 3, 4, 5} is 2

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 (≤ 100000).

The following n lines describe the sequence.

Then follows 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
1
2
3
4
5
2
ADD 2 4 1
MIN 4 5

Sample Output

5

初始时给出一个序列,进行一下操作:

ADD x y D [x,y] 区间每个元素增加D

REVERSE x y 翻转区间[x,y]

REVOLVE x y t 区间[x,y]循环右移t位。

INSERT x p 在x之后插入p

DELETE x 删除元素x

MIN x y 询问区间[x,y]的最小值

注意REVOLVE 可以转化成3次REVERSE或者一次

ADD 和RECERSE采用lazy标记,每次更新两层

代码:

/*************************************************************************
    > File Name: Spaly.cpp
    > Author: acvcla
    > QQ:
    > Mail: [email protected]om
    > Created Time: 2014Äê11ÔÂ16ÈÕ ÐÇÆÚÈÕ 00ʱ14·Ö26Ãë
 ************************************************************************/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<cstdlib>
#include<ctime>
#include<set>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 2e5 + 100;
const int inf=1e9+7;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define pb push_back
int ch[maxn][2],pre[maxn],rev[maxn],siz[maxn],Min[maxn];
int root,tot;
int addv[maxn],A[maxn],tmp[maxn];
void newnode(int &x,int fa,int k)
{
	x=++tot;
	A[x]=k;
	Min[x]=k;
	siz[x]=1;
	pre[x]=fa;
	addv[x]=rev[x]=ch[x][1]=ch[x][0]=0;
}
void push_up(int x){
	if(!x)return;
	siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
	Min[x]=min(Min[ch[x][0]],Min[ch[x][1]]);
	Min[x]=min(Min[x],A[x]);
}
void upadte_rev(int x)
{
	if(!x)return ;
	swap(ch[x][0],ch[x][1]);
	rev[x]^=1;
}
void Modify(int x,int val){
	if(!x)return;
	A[x]+=val;
	Min[x]+=val;
	addv[x]+=val;
}
void push_down(int x)
{
	if(!x)return;
	if(addv[x]){
		Modify(ch[x][0],addv[x]);
		Modify(ch[x][1],addv[x]);
		addv[x]=0;
	}
	if(rev[x]){
		upadte_rev(ch[x][0]);
		upadte_rev(ch[x][1]);
		rev[x]^=1;
	}
}
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;
	ch[x][kind]=y;

	if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x;
	pre[x]=pre[y];
	pre[y]=x;
	push_up(y);
	push_up(x);
}
void Splay(int x,int goal)
{
	while(pre[x]!=goal){
		if(pre[pre[x]]==goal)Rotate(x,ch[pre[x]][0]==x);
		else{
			int y=pre[x];
			int kind=(ch[pre[y]][0]==y);
			if(ch[y][kind]==x){
				Rotate(x,!kind);
				Rotate(x,kind);
			}else{
				Rotate(y,kind);
				Rotate(x,kind);
			}
		}
	}
	if(goal==0)root=x;
}
void built(int &x,int L,int R,int fa)
{
	if(L>R)return;
	int mid=(R+L)>>1;
	newnode(x,fa,tmp[mid]);
	built(ch[x][0],L,mid-1,x);
	built(ch[x][1],mid+1,R,x);
	push_up(x);
}
void init(int n)
{
	siz[0]=pre[0]=0;
	root=tot=ch[0][0]=ch[0][1]=0;
	Min[0]=inf;
	newnode(root,0,inf);
	newnode(ch[root][1],root,inf);
	for(int i=1;i<=n;i++)scanf("%d",tmp+i);
	built(ch[ch[root][1]][0],1,n,ch[root][1]);
	push_up(ch[root][1]);
	push_up(root);
}
int Get_kth(int x,int k){
	push_down(x);
	int sz=siz[ch[x][0]]+1;
	if(sz==k)return x;
	if(sz>k)return Get_kth(ch[x][0],k);
	return Get_kth(ch[x][1],k-sz);
}
int Get_max(int x)
{
	push_down(x);
	while(ch[x][1])
	{
		x=ch[x][1];
		push_down(x);
	}
	return x;
}
void add(int L,int R,int v)
{
	Splay(Get_kth(root,L-1),0);
	Splay(Get_kth(root,R+1),root);
	Modify(ch[ch[root][1]][0],v);
}
void reverse(int L,int R)
{
	Splay(Get_kth(root,L-1),0);
	Splay(Get_kth(root,R+1),root);
	upadte_rev(ch[ch[root][1]][0]);
}
void revolve(int L,int R,int c)
{
    c  %= (R-L+1);
    if (!c)return;
	reverse(L,R);
    reverse(L,L+c-1);
    reverse(L+c,R);
}
void Insert(int x,int p)
{
	Splay(Get_kth(root,x),0);
	Splay(Get_kth(root,x+1),root);
	newnode(ch[ch[root][1]][0],ch[root][1],p);
	push_up(ch[root][1]);
	push_up(root);
}
void remove_root()
{
	push_down(root);
	if(!ch[root][0]){
		root=ch[root][1];
	}else{
		int t=Get_max(ch[root][0]);
		Splay(t,root);
		ch[t][1]=ch[root][1];
		pre[ch[root][1]]=t;
		root=t;
	}
	pre[root]=0;
	push_up(root);
}
void del(int x)
{
	Splay(Get_kth(root,x),0);
	remove_root();
}
int Query(int L,int R)
{
	Splay(Get_kth(root,L-1),0);
	Splay(Get_kth(root,R+1),root);
	return Min[ch[ch[root][1]][0]];
}
int main(int argc, char const *argv[])
{
		int n,m,L,R,x;
		scanf("%d",&n);
		init(n);
		scanf("%d",&m);
		char op[10];
		while(m--){
			scanf("%s",op);
			if(op[0]=='A'){
				scanf("%d%d%d",&L,&R,&x);
				add(L+1,R+1,x);
			}else if(op[0]=='D'){
				scanf("%d",&L);
				del(L+1);
			}else if(op[0]=='I'){
				scanf("%d%d",&L,&x);
				Insert(L+1,x);
			}else if(op[0]=='M'){
				scanf("%d%d",&L,&R);
				printf("%d\n",Query(L+1,R+1));
			}else if(op[0]=='R'){
				if(op[3]=='E'){
					scanf("%d%d",&L,&R);
					reverse(L+1,R+1);
				}else{
					scanf("%d%d%d",&L,&R,&x);
					revolve(L+1,R+1,x);
				}
			}
		}
		return 0;
}
时间: 2024-10-05 23:46:44

POJ 3580 Splay的相关文章

poj 3580 SuperMemo (Splay)

poj 3580 好恶心的题目,真是各种操作都来了个遍 ... 不过Splay树真是一种神奇的东西,通过旋转就能实现各种操作,而且方法也都相差不大 . 题意: 给出一个数字序列,有6种操作: (1) ADD x y d: 第x个数到第y个数加d . (2) REVERSE x y : 将区间[x,y]中的数翻转 . (3) REVOLVE x y t :将区间[x,y]旋转t次,如1 2 3 4 5 旋转2次后就变成4 5 1 2 3 . (4) INSERT x p :在第x个数后面插入p .

poj 3580 SuperMemo splay树模板题

题意: 给一个序列,对其进行各种操作.在对序列仅对操作的处理上,splay是比线段树强大的,虽然均摊复杂度均为logN,但它能支持1:在某个位置插入一些连续的数,2:在某个位置删除一些连续的数.只是splay随便一些200+行. 分析: 网上各种模板介绍漫天飞,这个还算简洁明了. 代码: //poj 3580 #include <stdio.h> #define maxN 200000 int N,T,node; int a[maxN],size[maxN],left[maxN],right[

POJ 3580 SuperMemo

裸Splay区间操作: 内存池+区间加减+区间翻转+插入+删除+维护最值 SuperMemo Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 8552   Accepted: 2801 Case Time Limit: 2000MS Description Your friend, Jackson is invited to a TV show called SuperMemo in which the participa

SuperMemo(POJ 3580)

SuperMemo Time Limit: 5000MS   Memory Limit: 65536K       Case Time Limit: 2000MS 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 parti

poj 3468 Splay 树

大二上的时候,写过一个AVL的操作演示,今天一看Splay,发现和AVL其实一样,加上线段树的基础,懒惰标记什么都知道,学起来轻松许多哦 我参考的模板来自这里  http://blog.csdn.net/u013480600/article/list/2 里面有大量的ch[r][0] ch[r][1]等 我建议用宏定义取代,写的时候方括号少打了很多,等做的题多得时候,我再把自己使用的模板发来 #include <cstdio> #include <cstring> #include

POJ 3580 - SuperMemo - [伸展树splay]

题目链接:http://poj.org/problem?id=3580 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 h

POJ 3580(SuperMemo-Splay区间加)[template:Splay V2]

SuperMemo Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 11384   Accepted: 3572 Case Time Limit: 2000MS Description Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to play a memorizing game

Splay树(多操作)——POJ 3580 SuperMemo

对应POJ题目:点击打开链接 SuperMemo Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 11309   Accepted: 3545 Case Time Limit: 2000MS Description Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to play a

又一道Splay吐血题 [POJ 3580] SuperMemo

SuperMemo Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 9878   Accepted: 3177 Case Time Limit: 2000MS Description Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to play a memorizing game.