splay2(区间修改+内存回收)
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
splay2(区间修改+内存回收)的更多相关文章
- linux内存源码分析 - 内存回收(匿名页反向映射)
本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 概述 看完了内存压缩,最近在看内存回收这块的代码,发现内容有些多,需要分几块去详细说明,首先先说说匿名页的反向映 ...
- Android 操作系统的内存回收机制(转载)
Android 操作系统的内存回收机制(转载) Android APP 的运行环境 Android 是一款基于 Linux 内核,面向移动终端的操作系统.为适应其作为移动平台操作系统的特殊需要,谷歌对 ...
- hiho一下20周 线段树的区间修改
线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题改了改,又出给了 ...
- Android内存回收机制
退出但不关闭: 这是Android对于Linux的优化.当 Android 应用程序退出时,并不清理其所占用的内存,Linux 内核进程也相应的继续存在,所谓“退出但不关闭”.从而使得用户调用程序时能 ...
- Java内存回收机制
在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方面工作都是由JVM自动完成的,降低了Java程序员的学习难度,避免了像C/C++直接操作内存的危险.但是,也正 ...
- hihoCode 1078 : 线段树的区间修改
#1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题 ...
- memcache的内存回收机制
memcache不会释放内存,而是重新利用. 在缓存的清除方面,memcache是不释放已分配内存.当已分配的内存所在的记录失效后,这段以往的内存空间,memcache只会重复利用. memcache ...
- Java的内存回收机制
原文出处: cnblogs-小学徒V 在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方面工作都是由JVM自动完成的,降低了Java程序员的学习难度,避免了像C ...
- [转载]Java的内存回收机制
转自:http://www.admin10000.com/document/1671.html 在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方面工作都是由J ...
随机推荐
- Python 之路Day13
匿名函数 一行函数 lambda == def -- 关键字 lambda x:x x 是普通函数的形参(位置,关键字……)可以不接收参数,可以不写 :x 是普通函数的函数值(只能返回一个数据类型), ...
- C++——动态内存分配3
动态创建多维数组 new 类型名T[下标表达式1][下标表达式2]…: 如果内存申请成功,new运算返回一个指向新分配内存首地址的指针,是一个T类型的数组,数组元素的个数为除最左边一维外各维下标表达 ...
- 【转】Error,java对常量池来说字符串xxx的UTF8表示过长的解决及其理解
做项目,客户端这里自己模拟json数据时,一时没忍住搞得json字符串太长了(idea上大概有600多行吧),这个问题就蹦出来了.老方法直接google.百度然后看到一堆有关String 字符串常量池 ...
- 题解 【洛谷P4995】跳跳!
一看题目名字,下意识地认为DP. 打开题目,发现是一道水的贪心,和DP没一分钱关系(毕竟是洛谷最水月赛的T2). 废话不多说. 看完题面,首先想到排序.要将乱序的石头高度变为有序,才能更好地想题. C ...
- 11g RAC添加用户表空间(数据文件)至文件系统(File System)的修正
前提:非TEMP.UNDO和SYSTEM表空间,这仨是大爷,您得搂着点.来自博客园AskScuti .客户是添加临时表空间数据文件时,不小心 ADD 到了文件系统中,然后发现,后悔了,还在OS层面 R ...
- 【转载】Hadoop Hive基础sql语法
转自:http://www.cnblogs.com/HondaHsu/p/4346354.html Hive 是基于Hadoop 构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在H ...
- SpringCloud大白话之服务注册中心
SpringCloud-Eureka白话说明 eureka.client.register-with-eureka 属性表示是否将自己注册到Eureka Server, 默认为true. 由于当前应用 ...
- SpringBoot+springDataJpa实现单表字段动态部分更新
写在前面 所谓的动态部分更新是指:并非对数据记录的所有字段整体更新,而是知道运行时才确定哪个或者哪些字段需要被更新. 1)Spring Data Jpa对于Entity的更新,是对数据表中Entity ...
- C++类几种初始化的顺序
首先给段代码: class A{ public: ; A():x(){cout<<"A(): x="<<x<<endl;} A(int a):x ...
- c数据结构 绪论
四种逻辑结构:1:集合结构 结构中的数据元素除了同属于同一个集合的关系外,无任何其他关系2:线性结构 结构中的数据元素之间存在着一对一的线性关系3:树形结构 结构中的数据元素之间存在着一对多的层次关系 ...