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

其中 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+100;
int num[MAXN];
struct SplayTree {int sz[MAXN];int ch[MAXN][2];int pre[MAXN];int rt,top;inline void down(int x){if(flip[x]) {flip[ L ] ^= 1;flip[ R ] ^= 1;swap(L,R);flip[x]=0;}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]=0;}}inline void up(int x){sz[x]=1+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]][1] == 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]][0] == x);else   {int y=pre[x],z=pre[y];int f = (ch[z][0]==y);if(ch[y][f] == x) Rotate(x,!f),Rotate(x,f);else Rotate(y,f),Rotate(x,f);}}up(x);if(goal==0) rt=x;}inline void RTO(int k,int goal){//将第k位数旋转到goal的下面int x=rt;down(x);while(sz[ L ]+1 != k) {if(k < sz[ L ] + 1 ) x=L;else {k-=(sz[ L ]+1);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]=0;L = R = 0;  pre[x] = f;sz[x]=1; val[x]=c;mi[x]=c; add[x]=0;}inline void build(int &x,int l,int r,int f){if(l>r) return ;int m=(l+r)>>1;Newnode(x,num[m],f);build(L , l , m-1 , x);build(R , m+1 , r , x);pre[x]=f;up(x);}//终于明白初始化结点0的用处了。就是所有的叶子结点,是终止结点inline void init(int n){ch[0][0]=ch[0][1]=pre[0]=sz[0]=0;rt=top=0; flip[0]=0; val[0]=0;add[0]=0;mi[0]=INF;Newnode(rt,INF,0);Newnode(ch[rt][1],INF,rt);sz[rt]=2;build(KT,1,n,ch[rt][1]);up(ch[rt][1]);up(rt);}void Del(){int t=rt;if(ch[rt][1]) {rt=ch[rt][1];RTO(1,0);ch[rt][0]=ch[t][0];if(ch[rt][0]) pre[ch[rt][0]]=rt;}else rt=ch[rt][0];pre[rt]=0;up(rt);}void ADD(int a,int b,int d){if(a>b)swap(a,b);RTO(a,0);RTO(b+2,rt);add[KT]+=d;val[KT]+=d;mi[KT]+=d;}void REVERSE(int a,int b){if(a>b)swap(a,b);RTO(a,0);RTO(b+2,rt);flip[KT]^=1;}//t有可能为负void REVOLVE(int x,int y,int t){if(x>y)swap(x,y);t=t%(y-x+1);t=(t+y-x+1)%(y-x+1);if(t==0)return;int l=y-t+1;int r=y+2;RTO(l,0);RTO(r,rt);int tmp=KT;KT=0;up(ch[rt][1]);up(rt);RTO(x,0);RTO(x+1,rt);KT=tmp;pre[tmp]=ch[rt][1];up(ch[rt][1]);up(rt);}void INSERT(int x,int p){RTO(x+1,0);RTO(x+2,rt);Newnode(KT,p,ch[rt][1]);up(ch[rt][1]);up(rt);}void DELETE(int x){RTO(x,0);RTO(x+2,rt);KT=0;up(ch[rt][1]);up(rt);}int  MIN(int x,int y){if(x>y)swap(x,y);RTO(x,0);RTO(y+2,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,1,n)scanf("%d",&num[i]);scanf("%d",&m);spt.init(n);char op[10];int a,b,c;REP(i,1,m){scanf("%s",op);if(op[0]=='A'){scanf("%d%d%d",&a,&b,&c);spt.ADD(a,b,c);}else if(op[0]=='I'){scanf("%d%d",&a,&b);spt.INSERT(a,b);}else if(op[0]=='D'){scanf("%d",&a);spt.DELETE(a);}else if(op[0]=='M'){scanf("%d%d",&a,&b);int ans=spt.MIN(a,b);printf("%d\n",ans);}else if(strcmp(op,"REVERSE")==0){scanf("%d%d",&a,&b);spt.REVERSE(a,b);}else if(strcmp(op,"REVOLVE")==0){scanf("%d%d%d",&a,&b,&c);spt.REVOLVE(a,b,c);}}}return 0;
}

转载于:https://www.cnblogs.com/arbitrary/p/3252862.html

POJ-3580-SuperMemo(splay的各种操作)相关推荐

  1. POJ 3580 SuperMemo

    http://poj.org/problem?id=3580 题目大意说给你一个数列,有区间同加一个数.区间翻转操作.区间滚动操作.删除一个数.插入一个数,查询区间最小值这些操作. 我是使用Splay ...

  2. POJ 3580. SuperMemo

    Description Input The first line contains n (n ≤ 100000). The following n lines describe the sequenc ...

  3. POJ 3580 SuperMemo 伸展树

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

  4. POJ 3580 SuperMemo(伸展树的基本操作)

    题目大意:给你六个操作,让你实现这些功能. 解题思路:伸展树的基本应用,用伸展数实现各种功能. SuperMemo Time Limit: 5000MS   Memory Limit: 65536K ...

  5. splay的一些操作

    秦同学的详细版本 splay就是一种将树上的一个节点经过旋转到节点的一种操作,来保持树的平衡 splay本质:二叉搜索树 特点:结点x的左子树权值都小于x的权值,右子树权值都大于x的权值 如果当前处于 ...

  6. poj 3580 splay

    维修数列的简化版,要求的操作还是挺多的,运行时间大概1s. 1 #include <iostream> 2 #include <cstring> 3 #include < ...

  7. Poj 2887-Big String Splay

    题目:http://poj.org/problem?id=2887 Big String Time Limit: 1000MS   Memory Limit: 131072K Total Submis ...

  8. 【BZOJ1500】【codevs1758】维修数列,简析Splay的综合操作

    Time:2016.05.12 Author:xiaoyimi 转载注明出处谢谢 传送门1 传送门2 思路: 我的天啊! Splay大板子! 调了好久啊! 这里的Splay没有判断的key值,换一种说 ...

  9. Splay树各操作--数组

    伸展树删除元素非常方便.. View Code #include <stdio.h>#include <string.h>#include <algorithm># ...

  10. 三大平衡树(Treap + Splay + SBT)总结+模板

    Treap树 核心是 利用随机数的二叉排序树的各种操作复杂度平均为O(lgn) Treap模板: #include <cstdio> #include <cstring> #i ...

最新文章

  1. Wireshark小技巧:将IP显示为域名
  2. 转载 Xmlhttprequest对象池
  3. sbt構建一個spark工程(scala+spark+sbt)
  4. Hibernate查询缓存如何工作
  5. 如何更好的掌握一个知识点_如何成为一个更好的讲故事的人3个关键点
  6. python 多线程 popen ping指定IP是否在线 判断连通
  7. python信用评分卡_基于Python的信用评分卡模型分析(二)
  8. Linux-IPC进程间通信(day11)
  9. 佳能G1810G2810G1800G2800G3800 废墨 手动清零方法
  10. 惠普服务器安装系统流程,惠普服务器怎样安装系统?
  11. Java模拟猜数字小游戏,有次数限制,并且输出猜测次数。
  12. 鸡小德手机小常识 如何鉴定手机是否为行货
  13. python特殊函数_SciPyTutorial-特殊函数
  14. 无刷直流电动机矢量控制(一)——无刷直流电机(BLDC)与永磁同步电机(PMSM)的相同点和区别
  15. java 控制台输入
  16. AIX(Advanced Interactive eXecutive)操作系统
  17. 个人实践,B450锐龙3600安装原版win7方法
  18. Flutter BLoC
  19. 买不起switch的人如何使用手机+平板玩Just Dance
  20. 利用VBA代码解决Excel下拉菜单跳过空单元格的问题

热门文章

  1. 注意力机制-CA注意力-Coordinate attention
  2. 如何制作千千静听个性皮肤
  3. 如何做一个优秀的管理者
  4. 设计师工作经验_得到我作为设计师的第一份工作
  5. reg51 reg52区别
  6. 超级大富翁主题团建活动
  7. ASP.Net使用ADSI操作IIS遇到的0x80070005等问题研究记录
  8. 买土豆的故事(转中外管理)
  9. python公开直播课_今晚Python与人工智能直播课来袭,Mars喊你快上车
  10. [人工智能-深度学习-35]:卷积神经网络CNN - 常见分类网络- GoogLeNet Incepetion网络架构分析与详解