题意:对数组进行各种操作

其中 REVOLVE右移操作。将区间[a,b]右移c位

首先c可能比较多,可以先对区间长度取模。

在右移之后,可以发现[a,b]被分为两个区间[a,b-c]  [b-c+1,b],将后者插入到前者之前即可。

// File Name: ACM/POJ/3580.cpp
// Author: Zlbing
// Created Time: 2013年08月10日 星期六 10时51分07秒 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3fffffff
#define LL long long
#define REP(i,r,n) for(int i=r;i<=n;i++)
#define RREP(i,n,r) for(int i=n;i>=r;i--)
#define L ch[x][0]
#define R ch[x][1]
#define KT (ch[ ch[rt][1] ][0])
const int MAXN = 2e5+;
int num[MAXN];
struct SplayTree {
int sz[MAXN];
int ch[MAXN][];
int pre[MAXN];
int rt,top;
inline void down(int x){
if(flip[x]) {
flip[ L ] ^= ;
flip[ R ] ^= ;
swap(L,R);
flip[x]=;
}
if(add[x])
{
if(L)
{
add[L]+=add[x];
mi[L]+=add[x];
val[L]+=add[x];
}
if(R)
{
add[R]+=add[x];
mi[R]+=add[x];
val[R]+=add[x];
}
add[x]=;
}
}
inline void up(int x){
sz[x]=+sz[ L ] + sz[ R ];
mi[x]=min(val[x],min(mi[L],mi[R]));
}
inline void Rotate(int x,int f){
int y=pre[x];
down(y);
down(x);
ch[y][!f] = ch[x][f];
pre[ ch[x][f] ] = y;
pre[x] = pre[y];
if(pre[x]) ch[ pre[y] ][ ch[pre[y]][] == y ] =x;
ch[x][f] = y;
pre[y] = x;
up(y);
}
inline void Splay(int x,int goal){//将x旋转到goal的下面
down(x);////防止pre[x]就是目标点,下面的循环就进不去了,x的信息就传不下去了
while(pre[x] != goal){
down(pre[pre[x]]); down(pre[x]);down(x);//在旋转之前需要先下传标记,因为节点的位置可能会发生改变
if(pre[pre[x]] == goal) Rotate(x , ch[pre[x]][] == x);
else {
int y=pre[x],z=pre[y];
int f = (ch[z][]==y);
if(ch[y][f] == x) Rotate(x,!f),Rotate(x,f);
else Rotate(y,f),Rotate(x,f);
}
}
up(x);
if(goal==) rt=x;
}
inline void RTO(int k,int goal){//将第k位数旋转到goal的下面
int x=rt;
down(x);
while(sz[ L ]+ != k) {
if(k < sz[ L ] + ) x=L;
else {
k-=(sz[ L ]+);
x = R;
}
down(x);
}
Splay(x,goal);
}
void vist(int x){
if(x){
printf("结点%2d : 左儿子 %2d 右儿子 %2d %2d flip:%d\n",x,L,R,val[x],flip[x]);
printf("结点%2d mi=%2d\n",x,mi[x]);
vist(L);
vist(R);
}
}
void Newnode(int &x,int c,int f){
x=++top;flip[x]=;
L = R = ; pre[x] = f;
sz[x]=; val[x]=c;
mi[x]=c; add[x]=;
}
inline void build(int &x,int l,int r,int f){
if(l>r) return ;
int m=(l+r)>>;
Newnode(x,num[m],f);
build(L , l , m- , x);
build(R , m+ , r , x);
pre[x]=f;
up(x);
} //终于明白初始化结点0的用处了。就是所有的叶子结点,是终止结点
inline void init(int n){
ch[][]=ch[][]=pre[]=sz[]=;
rt=top=; flip[]=; val[]=;
add[]=;mi[]=INF;
Newnode(rt,INF,);
Newnode(ch[rt][],INF,rt);
sz[rt]=;
build(KT,,n,ch[rt][]);
up(ch[rt][]);up(rt);
}
void Del(){
int t=rt;
if(ch[rt][]) {
rt=ch[rt][];
RTO(,);
ch[rt][]=ch[t][];
if(ch[rt][]) pre[ch[rt][]]=rt;
}
else rt=ch[rt][];
pre[rt]=;
up(rt);
}
void ADD(int a,int b,int d)
{
if(a>b)swap(a,b);
RTO(a,);
RTO(b+,rt);
add[KT]+=d;
val[KT]+=d;
mi[KT]+=d;
}
void REVERSE(int a,int b)
{
if(a>b)swap(a,b);
RTO(a,);
RTO(b+,rt);
flip[KT]^=;
}
//t有可能为负
void REVOLVE(int x,int y,int t)
{
if(x>y)swap(x,y);
t=t%(y-x+);
t=(t+y-x+)%(y-x+);
if(t==)return;
int l=y-t+;
int r=y+;
RTO(l,);
RTO(r,rt);
int tmp=KT;
KT=;
up(ch[rt][]);up(rt); RTO(x,);
RTO(x+,rt);
KT=tmp;pre[tmp]=ch[rt][];
up(ch[rt][]);up(rt);
}
void INSERT(int x,int p)
{
RTO(x+,);
RTO(x+,rt);
Newnode(KT,p,ch[rt][]);
up(ch[rt][]);up(rt);
}
void DELETE(int x)
{
RTO(x,);
RTO(x+,rt);
KT=;
up(ch[rt][]);up(rt);
}
int MIN(int x,int y)
{
if(x>y)swap(x,y);
RTO(x,);
RTO(y+,rt);
return mi[KT];
}
int flip[MAXN];
int val[MAXN];
int mi[MAXN];
int add[MAXN];
}spt; int main()
{
int n,m;
while(~scanf("%d",&n))
{
REP(i,,n)
scanf("%d",&num[i]);
scanf("%d",&m);
spt.init(n);
char op[];
int a,b,c;
REP(i,,m)
{
scanf("%s",op);
if(op[]=='A')
{
scanf("%d%d%d",&a,&b,&c);
spt.ADD(a,b,c);
}
else if(op[]=='I')
{
scanf("%d%d",&a,&b);
spt.INSERT(a,b);
}
else if(op[]=='D')
{
scanf("%d",&a);
spt.DELETE(a);
}
else if(op[]=='M')
{
scanf("%d%d",&a,&b);
int ans=spt.MIN(a,b);
printf("%d\n",ans);
}
else if(strcmp(op,"REVERSE")==)
{
scanf("%d%d",&a,&b);
spt.REVERSE(a,b);
}
else if(strcmp(op,"REVOLVE")==)
{
scanf("%d%d%d",&a,&b,&c);
spt.REVOLVE(a,b,c);
}
}
}
return ;
}

POJ-3580-SuperMemo(splay的各种操作)的更多相关文章

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

    相应POJ题目:点击打开链接 SuperMemo Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 11309   Accept ...

  2. poj 3580 SuperMemo

    题目连接 http://poj.org/problem?id=3580 SuperMemo Description Your friend, Jackson is invited to a TV sh ...

  3. POJ 3580 - SuperMemo - [伸展树splay]

    题目链接:http://poj.org/problem?id=3580 Your friend, Jackson is invited to a TV show called SuperMemo in ...

  4. POJ 3580 SuperMemo (splay tree)

    SuperMemo Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6841   Accepted: 2268 Case Ti ...

  5. 平衡树(Splay):Splaytree POJ 3580 SuperMemo

    SuperMemo         Description Your friend, Jackson is invited to a TV show called SuperMemo in which ...

  6. POJ 3580 SuperMemo (FHQ_Treap)

    题意:让你维护一个序列,支持以下6种操作: ADD x y d: 第x个数到第y个数加d . REVERSE x y : 将区间[x,y]中的数翻转 . REVOLVE x y t :将区间[x,y] ...

  7. POJ 3580 SuperMemo 伸展树

    题意: 维护一个序列,支持如下几种操作: ADD x y D:将区间\([x,y]\)的数加上\(D\) REVERSE x y:翻转区间\([x,y]\) REVOLVE x y T:将区间\([x ...

  8. Splay 的区间操作

    学完Splay的查找作用,发现和普通的二叉查找树没什么区别,只是用了splay操作节省了时间开支. 而Splay序列之王的称号可不是白给的. Splay真正强大的地方是他的区间操作. 怎么实现呢? 我 ...

  9. hdu 1890 Robotic SortI(splay区间旋转操作)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1890 题解:splay又一高级的功能,区间旋转这个是用线段树这些实现不了的,这题可以学习splay的旋 ...

随机推荐

  1. WWDC-UIKit 中协议与值类型编程实战

    本文为 WWDC 2016 Session 419 的部分内容笔记.强烈推荐观看. 设计师来需求了 在我们的 App 中,通常需要自定义一些视图.例如下图: 我们可能会在很多地方用到右边为内容,左边有 ...

  2. 【Android】广播BrocastReceiver

    1.Android中广播主要分为两种:标准广播和有序广播. 标准广播:完全异步执行.广播发出后,所有的广播接收器几乎在同一刻收到广播事件,没有先后顺序之分. 优点:效率高 缺点:不能被截断 有序广播: ...

  3. CentOS使用sendmail发送邮件

    1.安装sendmail yum -y install sendmail 2.启动sendmail服务 service sendmail start 3.将发件内容写入mail.txt mail -s ...

  4. 【css面试题】三个DIV要求水平对齐,左右两个DIV宽度固定为100px,中间那个DIV充满剩余的宽度(至少2种方法)

    这是我在一家公司面试时遇到的问题,当时没有答上来!! 所以看到的小伙伴一定要注意了!! 变化浏览器宽度可看到效果: 左 右 中 然后我们来看看代码: 第一种方法:(浮动) <style type ...

  5. Java排序8大算法实现

    概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大, ...

  6. qrcode-php生成二维码

    调用PHP QR Code非常简单,如下代码即可生成一张内容为"http://www.baidu.com"的二维码. include 'phpqrcode.php'; QRcode ...

  7. node-http-proxy修改响应结果

    最近在项目中使用node-http-proxy遇到需要修改代理服务器响应结果需求,该库已提供修改响应格式为html的方案:Harmon,而项目中返回格式统一为json,使用它感觉太笨重了,所以自己写了 ...

  8. Spring 创建bean的时机

    默认在启动spring容器的时候,spring容器配置文件中的类就已经创建完成对象了        在<bean>中添加属性lazy-init,默认值为false.    true  在c ...

  9. fish code

    <embed width="272" height="180" type="application/x-shockwave-flash" ...

  10. 16_用LVM扩展xfs文件系统(当分区空间不够时)

    1. 查看当前卷组空间(volume group)使用情况 [root@localhost ~]# vgdisplay 从下面的代码中发现剩余空间为0 --- Volume group --- VG ...