您的位置:首页 > 其它

POJ 题目3580 SuperMemo(Splay Tree区间加,区间翻转,区间右移,插入删除,区间最小值)

2015-09-07 08:24 573 查看
SuperMemo

Time Limit: 5000MSMemory Limit: 65536K
Total Submissions: 11616Accepted: 3656
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 participant a sequence of numbers, {A1, A2, ... An}.
Then the host performs a series of operations and queries on the sequence which consists:

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}
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}
REVOLVE x y T: rotate sub-sequence {Ax ... Ay} T times. For example, performing "REVOLVE 2 4 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 2, 5}
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}
DELETE x: delete Ax. For example, performing "DELETE 2" on {1, 2, 3, 4, 5} results in {1, 3, 4, 5}
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 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
1
2
3
4
5
2
ADD 2 4 1
MIN 4 5

Sample Output
5

Source

POJ Founder Monthly Contest – 2008.04.13, Yao Jinyu

给定一个数列a1,a2,...an
* 进行以下6种操作
* ADD x y D :给第x个数到第y个数加D(增加一个add进行延迟标记)
* REVERSE x y :反转[x,y]之间的数(伸展树经典操作)
* REVOLVE x y T:循环右移T次(先把T对长度进行取模,然后就相当于把[y-T+1,y]放在[x,y-T]前面)
* INSERT x P:在第x个数后面插入P (经典的插入)
* DELETE x:删除第x个数(删除操作)
* MIN x y:查询[x,y]之间最小的数(标记)

ac代码

Problem: 3580		User: kxh1995
Memory: 3736K		Time: 1266MS
Language: C++		Result: Accepted


#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define min(a,b) (a>b?b:a)
#define N 200010
#define Maxn 200010
#define INF 0x7FFFFFFF
using namespace std;
int pre
,key
,ch
[2],root,top,rev
,num
,add
,minv
,size;
int st
;
int a
;
void newnode(int &r,int fa,int val)
{
if(top!=-1)
r=st[top--];
else
r=++size;
pre[r]=fa;
num[r]=1;
rev[r]=0;
key[r]=minv[r]=val;
ch[r][0]=ch[r][1]=add[r]=0;
}
void pushup(int r)
{
num[r]=num[ch[r][1]]+num[ch[r][0]]+1;
minv[r]=min(minv[ch[r][1]],minv[ch[r][0]]);
minv[r]=min(minv[r],key[r]);
}
void pushdown(int r)
{
if(add[r])
{
if(ch[r][0])
{
add[ch[r][0]]+=add[r];
key[ch[r][0]]+=add[r];
minv[ch[r][0]]+=add[r];
}
if(ch[r][1])
{
add[ch[r][1]]+=add[r];
key[ch[r][1]]+=add[r];
minv[ch[r][1]]+=add[r];
}
add[r]=0;
}
if(rev[r])
{
rev[ch[r][0]]^=1;
rev[ch[r][1]]^=1;
swap(ch[r][0],ch[r][1]);
rev[r]=0;
}
}
void rotate(int x,int kind)
{
int y=pre[x];
pushdown(y);
pushdown(x);  ////////
ch[y][!kind]=ch[x][kind];
pre[ch[x][kind]]=y;
if(pre[y])
{
ch[pre[y]][ch[pre[y]][1]==y]=x;
}
pre[x]=pre[y];
ch[x][kind]=y;
pre[y]=x;
pushup(y);
}
/*void splay(int r,int goal)   //也行
{
pushdown(r);
while(pre[r]!=goal)
{
if(pre[pre[r]]==goal)
{
pushdown(pre[r]);
pushdown(r);
rotate(r,ch[pre[r]][0]==r);
}
else
{
int y=pre[r];
pushdown(pre[y]);
pushdown(y);
pushdown(r);
int kind=ch[pre[y]][0]==y;
if(ch[y][kind]==r)
{
rotate(r,!kind);
rotate(r,kind);
}
else
{
rotate(r,kind);
rotate(r,kind);
}
}
}
pushup(r);
if(goal==0)
root=r;
} */
void splay(int r,int goal)
{
if(r!=goal)
{
pushdown(r);
while(pre[r]!=goal)
{
if(ch[pre[r]][0]==r)
rotate(r,1);
else
rotate(r,0);
}
pushup(r);
if(!goal)
root=r;
}
}
int select(int k)
{
int x;
pushdown(root);
for(x=root;num[ch[x][0]]+1!=k;)
{
if(num[ch[x][0]]+1>k)
x=ch[x][0];
else
{
k-=num[ch[x][0]]+1;
x=ch[x][1];
}
pushdown(x);
}
return x;
}
void Add(int x,int y,int val)
{
int t;
x=select(x-1);
y=select(y+1);
splay(x,0);
splay(y,x);
t=ch[y][0];
add[t]+=val;
key[t]+=val;
minv[t]+=val;
pushup(y);
pushup(x);
}
void Rev(int x,int y)
{
x=select(x-1);
y=select(y+1);
splay(x,0);
splay(y,x);
rev[ch[y][0]]^=1;
}
void revol(int x,int y,int t)
{
int cnt=y-x+1;
t%=cnt;
if(t<0)
t+=cnt;
if(t)
{
Rev(x,y-t);
Rev(y-t+1,y);
Rev(x,y);
}
}
void build(int &x,int l,int r,int fa)
{
if(l>r)
return;
int mid=(l+r)>>1;
newnode(x,fa,a[mid]);
build(ch[x][0],l,mid-1,x);
build(ch[x][1],mid+1,r,x);
pushup(x);
}
void init(int n)
{
root=size=0;
top=-1;
rev[0]=0;
ch[0][0]=ch[0][1]=0;
pre[0]=add[0]=num[0]=0;
key[0]=minv[0]=INF;
newnode(root,0,INF);
newnode(ch[root][1],root,INF);
build(ch[ch[root][1]][0],1,n,ch[root][1]);
pushup(ch[root][1]);
pushup(root);
}
void insert(int x,int val)
{
int a,b;
a=select(x);
b=select(x+1);
splay(a,0);
splay(b,a);
newnode(ch[b][0],b,val);
pushup(b);
pushup(a);
}
void remove(int x)
{
int a,b;
a=select(x-1);
b=select(x+1);
splay(a,0);
splay(b,a);
st[++top]=ch[b][0];
ch[b][0]=0;
pushup(b);
pushup(a);
}
int Min(int x,int y)
{
x=select(x-1);
y=select(y+1);
splay(x,0);
splay(y,x);
return minv[ch[y][0]];
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int i;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
init(n);
int q;
scanf("%d",&q);
while(q--)
{
int x,y,val;
char op[10];
scanf(" %s",op);
scanf("%d",&x);
if(strcmp(op,"ADD")==0)
{
scanf("%d%d",&y,&val);
Add(x+1,y+1,val);
}
else
if(strcmp(op,"REVERSE")==0)
{
scanf("%d",&y);
Rev(x+1,y+1);
}
else
if(strcmp(op,"REVOLVE")==0)
{
scanf("%d%d",&y,&val);
revol(x+1,y+1,val);
}
else
if(strcmp(op,"INSERT")==0)
{
scanf("%d",&y);
insert(x+1,y);
}
else
if(strcmp(op,"DELETE")==0)
{
remove(x+1);
}
else
if(strcmp(op,"MIN")==0)
{
scanf("%d",&y);
printf("%d\n",Min(x+1,y+1));
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: