poj3580

要求写一种数据结构;

对一个序列进行

区间增减(add); 区间翻转(reverse);  区间移动(revolve);

插入(insert);   删除(delete);          求区间最小值(min);

据说各种方法都可以做,但是只学了splay;

对于(revolve)是指,将区间[x,y]旋转t次

{1,2,3,4,5}   revolve(2,4,2);    {1,2,3,4,5}->{1,4,2,3,5}->{1,3,2,4,5}

PS:小常数rotate & splay操作(zuo si)

 void small_const_rotate(int x,int d){
int y=T[x].fa;
T[y].son[!d]=T[x].son[d];
T[T[x].son[d]].fa=y;
if(T[y].fa) T[T[y].fa].son[T[T[y].fa].son[]==y]=x;
T[x].fa=T[y].fa,T[x].son[d]=y;
T[y].fa=x;
up(y);
}

small_const_rotate

 void small_const_splay(int x,int goal){//伸展操作,将x调整到goal下面
lazy(x);
while(T[x].fa!=goal){
if(T[T[x].fa].fa==goal){
lazy(T[x].fa),lazy(x);
rotate(x,T[T[x].fa].son[]==x);//这题有反转操作,需要先lazy,在判断左右孩子
}
else{
lazy(T[T[x].fa].fa),lazy(T[x].fa),lazy(x);//这题有反转操作,需要先lazy,在判断左右孩子
int y=T[x].fa , k=(T[T[y].fa].son[]==y);
if(T[y].son[k]==x)rotate(x,k^),rotate(x,k);//两个方向不同,则先左旋再右旋
else rotate(y,k),rotate(x,k); //两个方向相同,相同方向连续两次
}
}
up(x);
if(goal==) root=x;
}

small_const_splay

模板如下:

 #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
#include <set>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout)
#define Front T[T[root].son[1]].son[0]
#define ls T[x].son[0]
#define rs T[x].son[1]
const int MAXN=+;
const int INF=(int)2e9;
int a[MAXN],n,m;
struct splay_tree{
struct Node{
int son[],fa,key,size,add,rev,min;
void init(){
son[]=son[]=fa=key=size=add=rev=;
min=INF;
}
}T[MAXN];
int root,tot,s[MAXN],top;//内存池、内存池容量 void NewNode(int &x,int fa,int key){
if(top)x=s[top--];
else x=++tot;
ls=rs=;
T[x].fa=fa,T[x].size=;
T[x].add=T[x].rev=;
T[x].key=T[x].min=key;
} void up_rev(int x){
if(x==)return;
swap(ls,rs);
T[x].rev^=;
} void up_add(int x,int val){
if(x==)return;
T[x].add+=val, T[x].key+=val, T[x].min+=val;
} void up(int x){
T[x].size=T[ls].size+T[rs].size+;
T[x].min=T[x].key;
if(ls)T[x].min=min(T[x].min,T[ls].min);
if(rs)T[x].min=min(T[x].min,T[rs].min);
} void lazy(int x){
if(T[x].rev){
up_rev(ls); up_rev(rs);
T[x].rev=;
}
if(T[x].add){
up_add(ls,T[x].add);
up_add(rs,T[x].add);
T[x].add=;
}
} void build(int &x,int l,int r,int fa){
if(l>r)return;
int mid=(l+r)>>;
NewNode(x,fa,a[mid]);
build(ls,l,mid-,x);
build(rs,mid+,r,x);
up(x);
} void init(){
root=tot=top=;
T[root].init();
NewNode(root,,INF);
NewNode(T[root].son[],root,INF);
build(Front,,n,T[root].son[]);
up(T[root].son[]);
up(root);
} void rotate(int x,int k){
int y=T[x].fa,z=T[y].fa;
T[y].son[k^]=T[x].son[k] ,T[T[x].son[k]].fa=y;
T[x].son[k]=y ,T[y].fa=x;
T[z].son[T[z].son[]==y]=x ,T[x].fa=z;
up(y);
} void splay(int x,int goal){
if(x==goal)return;
while(T[x].fa!=goal){
int y=T[x].fa,z=T[y].fa;
lazy(z),lazy(y),lazy(x);
int rx=T[y].son[]==x ,ry=T[z].son[]==y;
if(z==goal)rotate(x,rx);
else{
if(rx==ry)rotate(y,ry);
else rotate(x,rx);
rotate(x,ry);
}
}
up(x);
if(goal==)root=x;
} int kth(int x,int k){
lazy(x);
int s=T[ls].size+;
if(s==k)return x;
if(s>k)return kth(ls,k);
else return kth(rs,k-s);
} void erase(int x){
if(x){
s[++top]=x;
erase(ls);
erase(rs);
}
} void update_add(int l,int r,int val){
splay(kth(root,l),);
splay(kth(root,r+),root);
up_add(Front,val);
up(T[root].son[]);
up(root);
} void update_reverse(int l,int r){
splay(kth(root,l),);
splay(kth(root,r+),root);
up_rev(Front);
up(T[root].son[]);
up(root);
} void update_revolve(int l,int r,int t){
int len=r-l+; t=(t%len+len)%len;if(t==) return;
int k=r-t+;
splay(kth(root,k),);
splay(kth(root,r+),root);
int tmp=Front;
Front=;
up(T[root].son[]);
up(root);
splay(kth(root,l),);
splay(kth(root,l+),root);
Front=tmp;
T[Front].fa=T[root].son[];
up(T[root].son[]);
up(root);
} void update_insert(int x,int P){
splay(kth(root,x+),);
splay(kth(root,x+),root);
NewNode(Front,T[root].son[],P);
up(T[root].son[]);
up(root);
} void update_delete(int x){
splay(kth(root,x),);
splay(kth(root,x+),root);
erase(Front);
T[Front].fa=;
Front=;
up(T[root].son[]);
up(root);
} int query_min(int l,int r){
splay(kth(root,l),);
splay(kth(root,r+),root);
return T[Front].min;
} void work(){
char str[];int x,y,D,P,T;
scanf("%d",&n);for(int i=;i<=n;i++)scanf("%d",&a[i]);
init();
for(scanf("%d",&m);m--;){
scanf("%s%d",str,&x);
if(strcmp(str,"DELETE")==)update_delete(x);
else if(strcmp(str,"INSERT")==)scanf("%d",&P),update_insert(x,P);
else if(strcmp(str,"ADD")==)scanf("%d%d",&y,&D),update_add(x,y,D);
else if(strcmp(str,"REVERSE")==)scanf("%d",&y),update_reverse(x,y);
else if(strcmp(str,"MIN")==)scanf("%d",&y),printf("%d\n",query_min(x,y));
else if(strcmp(str,"REVOLVE")==)scanf("%d%d",&y,&T),update_revolve(x,y,T);
}
}
}poj3580;
int main(){poj3580.work();return ;}

poj3580

最新文章

  1. 【Java每日一题】20161027
  2. 说一下linux中shell的后台进程与前台进程
  3. ERP产品价格成本计算的几个方法(转)
  4. jenkins+ant+ssh远程部署服务glassfish
  5. linux下JDK,tomcat的安装与环境变量配置
  6. 【锋利的jQuery】中全局事件ajaxStart、ajaxStop不执行
  7. 远程shell脚本执行工具类
  8. mycat环境搭建
  9. 破解某普通话测试app会员
  10. 【转】分享两个基于MDK IDE的调试输出技巧
  11. thinkphp5 Request请求类
  12. 框架frame
  13. 编译lua-5.3.5时出错解决方法
  14. SQL的三种连接方式内连接、左连接、外连接
  15. mysql 中文编码问题
  16. 某gov的逻辑漏洞
  17. linux extundelete 删除文件恢复
  18. python第三方模块之paramiko模块
  19. VSAM:视频监控系统 A System for Video Surveillance and Monitoring
  20. [java] 简单的ConcurrentHashMap

热门文章

  1. MySQL进阶之索引
  2. Git分支规范说明
  3. 第十八次CSP认证游记 | 2019.12.15
  4. 诡异的Integer
  5. 《深入理解java虚拟机》读书笔记五——第六章
  6. 题解【AcWing279】自然数拆分
  7. centos8 常用软件
  8. Wannafly Camp 2020 Day 2A 托米的字符串
  9. 条件锁Condition
  10. nginx的配置总结,有时间自己整理