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(区间修改+内存回收)的更多相关文章

  1. linux内存源码分析 - 内存回收(匿名页反向映射)

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 概述 看完了内存压缩,最近在看内存回收这块的代码,发现内容有些多,需要分几块去详细说明,首先先说说匿名页的反向映 ...

  2. Android 操作系统的内存回收机制(转载)

    Android 操作系统的内存回收机制(转载) Android APP 的运行环境 Android 是一款基于 Linux 内核,面向移动终端的操作系统.为适应其作为移动平台操作系统的特殊需要,谷歌对 ...

  3. hiho一下20周 线段树的区间修改

    线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题改了改,又出给了 ...

  4. Android内存回收机制

    退出但不关闭: 这是Android对于Linux的优化.当 Android 应用程序退出时,并不清理其所占用的内存,Linux 内核进程也相应的继续存在,所谓“退出但不关闭”.从而使得用户调用程序时能 ...

  5. Java内存回收机制

    在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方面工作都是由JVM自动完成的,降低了Java程序员的学习难度,避免了像C/C++直接操作内存的危险.但是,也正 ...

  6. hihoCode 1078 : 线段树的区间修改

    #1078 : 线段树的区间修改 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 对于小Ho表现出的对线段树的理解,小Hi表示挺满意的,但是满意就够了么?于是小Hi将问题 ...

  7. memcache的内存回收机制

    memcache不会释放内存,而是重新利用. 在缓存的清除方面,memcache是不释放已分配内存.当已分配的内存所在的记录失效后,这段以往的内存空间,memcache只会重复利用. memcache ...

  8. Java的内存回收机制

    原文出处: cnblogs-小学徒V 在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方面工作都是由JVM自动完成的,降低了Java程序员的学习难度,避免了像C ...

  9. [转载]Java的内存回收机制

    转自:http://www.admin10000.com/document/1671.html 在Java中,它的内存管理包括两方面:内存分配(创建Java对象的时候)和内存回收,这两方面工作都是由J ...

随机推荐

  1. jpa报错object references an unsaved transient instance

    错误原因: 在调用hibernate存储数据时,需要将数据库中表对应的持久类对象作为参数传递.如果这时的对象中有其他的表字段属性并且是引用对象类型,那么这个属性必须是持久态或者是null的,瞬时态和脱 ...

  2. ReportViewer Win32Exception (0x80004005): 创建窗口句柄时出错

    System.ComponentModel.Win32Exception (0x80004005): 创建窗口句柄时出错. 在 System.Windows.Forms.NativeWindow.Cr ...

  3. 1080 Graduate Admission

    大致题意就是有N个学生,有M个学校,每个学校的名额都是正整数.每个学生可以填K个学校志愿,N个学生一起排名以后,排名高的学生先挑学校,不保护一志愿. 题目要求: 首先,把所有学生按总成绩SUM(GE+ ...

  4. Gin_中间件

    gin可以构建中间件,但它只对注册过的路由函数起作用 对于分组路由,嵌套使用中间件,可以限定中间件的作用范围 中间件分为全局中间件,单个路由中间件和群组中间件 gin中间件必须是一个 gin.Hand ...

  5. Vue中常见参数传递方式

    文章内容:这里只有vue中父子组件传参.路由间的传参 (另外还有vuex.储存本地.中央bus等方式) 一.父子组件 1.1父传子(props) <!-- 父组件father.vue --> ...

  6. 如何架构一个 React 项目?

    编程有点像搞园艺.比起竭力去对付BUG(虫子),我们更愿意把一切弄得整洁有序,以免最后落得个身在荒野丛林中.低劣的架构会拖我们的后腿,也会使得BUG更容易钻进系统里去. 想要对你的项目进行架构,方法有 ...

  7. 【转】Java Future 怎么用 才算是真正异步

    接着上一篇继续并发包的学习,本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果.        Callable接口类似于Runnable,从名字就可以看出来了,但 ...

  8. Java面向对象--类和对象

    面向对象是相对于面向过程而言的,是软件开发方法.面向对象把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统设计,更贴近事物的自然运行模式.本篇博客介绍Java面向对象的类和对象 目录: 面 ...

  9. mui H5+ 调取 相册 拍照 功能 上传图片 + 裁剪功能

    H5+ 相册拍照图片上传 点击用户头像后,弹出actionSheet,选择从相册或是拍照:选取照片后调用上传方法: 上传图片后调用PhotoClip.js  插件进行裁剪 具体流程 弹出actionS ...

  10. 智能手机中下一次被消灭的部件是电话卡和TF卡

    智能手机中下一次被消灭的部件是电话卡和TF卡. 侧滑实体键盘,实体拍照键,HDMI外接接口,实体切换双卡键,可拆卸后盖……这些都消亡了,被其更好的内在设计所取代.而电话卡和TF卡仍在使用.将来的智能手 ...