原帖:
http://fanhq666.blog.163.com/blog/static/819434262011021105212299/
你的Treap能支持以下操作吗?1.区间增减
2.区间求最小
3.区间反转(倒序)
4.区间移动(把一段剪切、粘贴)
不能?只能用splay? 其实,Treap也可以办到。
方法就是:设计把一个子树split成两个子树的算法,以及把两个子树merge的算法。 例:poj3580,代码见最后 另外一个应用:可持久化Treap
设计一个数据结构维护一个序列
插入一个元素
删除一个元素
移动连续的一段(就是剪切、粘贴)
*查询m次操作之前的第p个元素是谁
例:超级文本编辑器(我正在构思的一道题)
文本长度不超过100000
每次可以插入、删除、剪切粘贴
要求在线算法
每个操作10微秒时限,一共32M内存 这个可以参见算法导论,核心思想是:一个节点创建之后就不再删除。另外用垃圾回收。 poj3580
#include <cstdio>
#include <algorithm>
using namespace std;
int ran(){
static int x=1364684679;
x+=(x<<2)+1;
return x;
}
struct node{
int k,mn,delta,mark,w,sz;
node *l,*r;
static node* getnew(node *w=NULL){
static node *list=NULL;
if (w){
w->r=list;list=w;
return NULL;
}
if (!list){
node *q=new node[10000];
for (int i=0;i<10000;i++){
q[i].w=ran();
q[i].r=list;list=q+i;
}
}
node *p=list;list=list->r;
p->l=p->r=NULL;p->delta=p->mark=0;
return p;
}
void down(){
if (mark){
if (l)swap(l->l,l->r),l->mark^=1;
if (r)swap(r->l,r->r),r->mark^=1;
mark=0;
}
if (delta){
if (l)l->mn+=delta,l->delta+=delta,l->k+=delta;
if (r)r->mn+=delta,r->delta+=delta,r->k+=delta;
delta=0;
}
}
void update(){
mn=k;
if (l && mn>l->mn+delta)mn=l->mn+delta;
if (r && mn>r->mn+delta)mn=r->mn+delta;
sz=1;
if (l)sz+=l->sz;
if (r)sz+=r->sz;
}
};
#define SIZE(_) ((_)?(_)->sz:0)
struct Treap{
node *root;
Treap(){root=NULL;}
void ins(node *&p,int a,int k){
if (!p){
p=node::getnew();
p->k=p->mn=k;p->sz=1;
}else{
p->down();
if (SIZE(p->l)>=a){
ins(p->l,a,k);
node *q=p->l;
if (q->w<p->w){
q->down();
p->l=q->r;q->r=p;p=q;
p->r->update();
}
}else{
ins(p->r,a-SIZE(p->l)-1,k);
node *q=p->r;
if (q->w<p->w){
q->down();
p->r=q->l;q->l=p;p=q;
p->l->update();
}
}
p->update();
}
}
void ins(int a,int k){ins(root,a,k);}
static void merge(node *&p,node *x,node *y){
if (!x || !y){
p=x?x:y;
}else if (x->w<y->w){
x->down();
merge(x->r,x->r,y);
x->update();
p=x;
}else{
y->down();
merge(y->l,x,y->l);
y->update();
p=y;
}
}
void del(node *&p,int a){
p->down();
if (SIZE(p->l)==a){
node *q=p;
merge(p,p->l,p->r);
node::getnew(q);
}else if (SIZE(p->l)>a){
del(p->l,a);
p->update();
}else{
del(p->r,a-SIZE(p->l)-1);
p->update();
}
}
void del(int a){del(root,a);}
static void cut(node *p,node *&x,node *&y,int a){
if (a==0){
x=NULL;y=p;
}else if (a==SIZE(p)){
x=p;y=NULL;
}else{
p->down();
if (SIZE(p->l)>=a){
y=p;
cut(p->l,x,y->l,a);
y->update();
}else{
x=p;
cut(p->r,x->r,y,a-SIZE(p->l)-1);
x->update();
}
}
}
int ask(node *p,int a,int b){
if (a==0 && b==SIZE(p)-1)return p->mn;
p->down();
int u=SIZE(p->l);
int r=(a<=u && u<=b?p->k:~0u>>1);
if (a<u)r=min(r,ask(p->l,a,b>=u?u-1:b));
if (b>u)r=min(r,ask(p->r,a<=u?0:a-u-1,b-u-1));
return r;
}
int ask(int a,int b){return ask(root,a,b);}
void dfs(node *p,int lv){
if (p){
dfs(p->l,lv+1);
for (int i=0;i<lv;i++)putchar(' '),putchar(' ');
printf("%d %d %d %d %d\n",p->k,p->sz,p->mn,p->delta,p->mark);
dfs(p->r,lv+1);
}
}
void dfs(){dfs(root,0);puts("");}
}T;
void Ins(int a,int k){
//printf("ins %d %d\n",a,k);
T.ins(a,k);
}
void Del(int a){
//printf("del %d\n",a);
T.del(a);
}
void Revolve(int a,int b,int c){
//printf("revolve %d %d %d\n",a,b,c);
node *p,*q,*r,*s;
Treap::cut(T.root,p,q,a);
Treap::cut(q,q,r,b-a+1);
Treap::cut(r,r,s,c-b);
Treap::merge(p,p,r);
Treap::merge(p,p,q);
Treap::merge(T.root,p,s);
}
void Reverse(int a,int b){
//printf("reverse %d %d\n",a,b);
node *p,*q,*r;
Treap::cut(T.root,p,q,a);
Treap::cut(q,q,r,b-a+1);
q->mark^=1;swap(q->l,q->r);
Treap::merge(p,p,q);
Treap::merge(T.root,p,r);
}
void Add(int a,int b,int c){
//printf("add %d %d %d\n",a,b,c);
node *p,*q,*r;
Treap::cut(T.root,p,q,a);
Treap::cut(q,q,r,b-a+1);
//T.dfs(q,0);puts("");
q->k+=c;q->mn+=c;q->delta+=c;
//printf("c=%d\n",c);
//T.dfs(q,0);
//puts("");
Treap::merge(p,p,q);
Treap::merge(T.root,p,r);
}
int Ask(int a,int b){
//printf("ask %d %d\n",a,b);
return T.ask(a,b);
}
int main()
{
int N;
scanf("%d",&N);
for (int i=0;i<N;i++){
int x;
scanf("%d",&x);
Ins(i,x);
}
int M;
//T.dfs();
scanf("%d",&M);
char buf[100];
while (M--){
scanf("%s",buf);
if (buf[0]=='A'){
int x,y,d;
scanf("%d%d%d",&x,&y,&d);x--;y--;
Add(x,y,d);
//T.dfs();
}else if (buf[0]=='I'){
int x,y;
scanf("%d%d",&x,&y);
Ins(x,y);
}else if (buf[0]=='D'){
int x;
scanf("%d",&x);x--;
Del(x);
}else if (buf[0]=='M'){
int x,y;
scanf("%d%d",&x,&y);x--;y--;
printf("%d\n",Ask(x,y));
}else if (buf[3]=='E'){
int x,y;
scanf("%d%d",&x,&y);x--;y--;
Reverse(x,y);
}else{
int x,y,t;
scanf("%d%d%d",&x,&y,&t);x--;y--;
t%=(y-x+1);
t+=(y-x+1);
t%=(y-x+1);
if (t){
Revolve(x,y-t,y);
}
}
}
return 0;
} 文本编辑器
#include <cstdio>
#include <bits/stl_pair.h>
#include <queue>
#include <deque>
#include <algorithm>
using namespace std;
int ran(){
static int x=222313214;
x+=(x<<2)+1;
return x;
}
struct node{
int w,sz;
char k;
node *l,*r;
static node* getnew(node *p=NULL){
static node * list=NULL;
if (p){
p->w=ran();
p->r=list;list=p;
return NULL;
}
if (!list){
node *p=new node[10000];
for (int i=0;i<10000;i++){
p[i].r=list;list=p+i;
p[i].w=ran();
}
}
node *q=list;
list=list->r;
q->l=NULL;q->r=NULL;q->sz=1;
return q;
}
};
#define SIZE(_) ((_)?(_)->sz:0)
int M,curid;
queue<pair<int,node*> > Literbox;
deque<node*> Roots;
void giveback(node *p){
Literbox.push(make_pair(curid,p));
}
void dfs(node *p,int a,int b){
if (p){
int u=SIZE(p->l);
if (u>a)dfs(p->l,a,min(b,u-1));
if (a<=u && u<=b)putchar(p->k);
if (b>u)dfs(p->r,max(a-u-1,0),b-u-1);
}
}
node * combine(node *p,node *q){
if (!p || !q)return p?p:q;
if (p->w<q->w){
node *a=node::getnew();
a->k=p->k;
a->w=p->w;
a->sz=p->sz+q->sz;
a->l=p->l;
a->r=combine(p->r,q);
giveback(p);
return a;
}else{
node *a=node::getnew();
a->k=q->k;
a->w=q->w;
a->sz=p->sz+q->sz;
a->r=q->r;
a->l=combine(p,q->l);
giveback(q);
return a;
}
}
void cutdown(node *p,node *&x,node *&y,int a){
if (a==0)x=NULL,y=p;
else if (a==SIZE(p)){
x=p;y=NULL;
}else{
if (SIZE(p->l)+1<=a){
x=node::getnew();
x->k=p->k;x->w=p->w;
x->sz=a;
x->l=p->l;
cutdown(p->r,x->r,y,a-SIZE(p->l)-1);
giveback(p);
}else{
y=node::getnew();
y->k=p->k;y->w=p->w;
y->sz=p->sz-a;
y->r=p->r;
cutdown(p->l,x,y->l,a);
giveback(p);
}
}
}
void treeadd(node *&p,node *q){
if (!p){
p=q;
}else{
if (p->w<q->w){
treeadd(p->r,q);
p->sz++;
}else{
q->l=p;q->sz=p->sz+1;
p=q;
}
}
}
void Insert(int i,char a){
node *p=node::getnew();
p->k=a;
node *x,*y;
cutdown(Roots.back(),x,y,i);
x=combine(x,p);x=combine(x,y);
Roots.push_back(x);
curid++;
}
void Delete(int i){
node *x,*y,*z;
cutdown(Roots.back(),x,y,i);
cutdown(y,y,z,1);
giveback(y);
x=combine(x,z);
Roots.push_back(x);
curid++;
}
void Revolve(int a,int b,int c){
node *p,*q,*r,*s;
cutdown(Roots.back(),p,q,a);
cutdown(q,q,r,b-a+1);
cutdown(r,r,s,c-b);
p=combine(p,r);
p=combine(p,q);
p=combine(p,s);
Roots.push_back(p);
curid++;
}
void Print(int a,int x,int y){
node *p=Roots.at(Roots.size()-1-a);
dfs(p,x,y);
puts("");
}
void readstr(vector<char> &a){
char c;
while (c=getchar(),c==10 || c==13 || c==' ');
while (c!=10 && c!=13){
a.push_back(c);
c=getchar();
}
}
int main()
{
scanf("%d",&M);
vector<char> chs;
readstr(chs);
node *r=NULL;
for (int i=0;i<(int)chs.size();i++){
node *p=node::getnew();
p->k=chs[i];
treeadd(r,p);
}
Roots.push_back(r);
curid=0;
char cmd[10];
while (scanf("%s",cmd)!=EOF){
if (cmd[0]=='I'){
int x;
scanf("%d",&x);
scanf("%s",cmd);
Insert(x,cmd[0]);
}else if (cmd[0]=='D'){
int x;
scanf("%d",&x);
Delete(x-1);
}else if (cmd[0]=='P'){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
Print(x,y-1,z-1);
}else if (cmd[0]=='C'){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
Revolve(x-1,y-1,z-1);
}
while (!Literbox.empty() && Literbox.front().first<curid-M){
node::getnew(Literbox.front().second);
Literbox.pop();
}
while ((int)Roots.size()>M)Roots.pop_front();
}
return 0;
}

【转载】【挖掘Treap的潜力】的更多相关文章

  1. [坑] treap

    先来挖个坑,以后有时间了来补上. treap: 学习资料: fhq式treap    http://hi.baidu.com/wdxertqdtscnwze/item/7b6a9419be7c68cd ...

  2. Impala内存优化(转载)

    一. 引言 Hadoop生态中的NoSQL数据分析三剑客Hive.HBase.Impala分别在海量批处理分析.大数据列式存储.实时交互式分析各有所长.尤其是Impala,自从加入Hadoop大家庭以 ...

  3. 如何提高AJAX客户端响应速度

    AJAX的出现极大的改变了Web应用客户端的操作模式,它使的用户可以在全心工作时不必频繁的忍受那令人厌恶的页面刷新.理论上AJAX技术在很大的程度上可以减少用户操作的等待时间,同时节约网络上的数据流量 ...

  4. Flink 实战:如何解决生产环境中的技术难题?

    大数据作为未来技术的基石已成为国家基础性战略资源,挖掘数据无穷潜力,将算力推至极致是整个社会面临的挑战与难题. Apache Flink 作为业界公认为最好的流计算引擎,不仅仅局限于做流处理,而是一套 ...

  5. 开源大数据生态下的 Flink 应用实践

    过去十年,面向整个数字时代的关键技术接踵而至,从被人们接受,到开始步入应用.大数据与计算作为时代的关键词已被广泛认知,算力的重要性日渐凸显并发展成为企业新的增长点.Apache Flink(以下简称 ...

  6. 在Asp.Net中操作PDF – iTextSharp - 使用表格

    使用Asp.Net生成PDF最常用的元素应该是表格,表格可以帮助比如订单或者发票类型的文档更加格式化和美观.本篇文章并不会深入探讨表格,仅仅是提供一个使用iTextSharp生成表格的方法介绍 使用i ...

  7. one_person年轻的程序员

    回顾大学三年,通过良师的教导和自身的刻苦学习,我已初步掌握如何运用计算机编程,也养成了认真对待学习和工作的好习惯! 在思想品德上,本人有良好道德修养,并有坚定的政治方向.我热爱祖国,热爱人民,遵纪守法 ...

  8. 程序员的成长与规划 | 送签名书啦 | StuQ专访foruok

    StuQ(InfoQ的朋友)对我做了一次专访,下面是原文. 福利:送一本签名版<你好哇,程序员>,参与方式在文末.

  9. 《大道至简》第三章读后感+ppt课后作业

                   大道至简读后感 ——第三章团队 古人云“三人为众”,众则是指团体或团队.对于一个团队而言,重要的是凝聚力,大家能在一起把拳头握紧那么产生的力量就不紧紧是能以1+1=2 来 ...

随机推荐

  1. web.xml 详解contextConfigLocation 转

    spring的应用初始化流程一直没有搞明白,刚刚又碰到了相关的问题.决定得好好看看这个流程.我们在开发spring的项目当中基本上都会在web.xml通过: <context-param> ...

  2. Delphi 6 Web Services初步评估

    Delphi 6 Web Services初步评估这是我刚到现在公司的时候(2001年8月份)所作的一份测试报告,现公布出来,希望能对大家有所帮助.因为当时d6刚刚发行,Web Service方面还存 ...

  3. C++之函数指针

    函数指针常用的有三类 1.指向普通函数的函数指针 2.指向类中静态成员函数的函数指针 3.指向类的成员函数的函数指针 一.指向普通函数的函数指针 #include <iostream> u ...

  4. MFC图形处理

    关于MFC绘图功能入门 创建Dialog based MFC工程    打开Resource view 下的Dialog主界面 添加Picture control控件,为此控件添加CStatic的co ...

  5. hdoj 2141 Can you find it?【二分查找+暴力】

    Can you find it? Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/10000 K (Java/Others ...

  6. Apple Pay强势来袭,开发者应做的事情

    "iOS8.1就已经有这个功能了,只是木有现在这么的火,现在的趋势是要火的节奏,因此很多电商平台B2B,P2P,C2C,X2X都有可能需要这个屌丝的付款功能了,在此简单的研究一下." ...

  7. MySQL 面试基础

    相关:http://blog.csdn.net/u013252072/article/details/52912385          http://blog.csdn.net/zhangliang ...

  8. 用ISE14.7引用功能强大的UltraEdit编写Verilog

    对于FPGA初学者来说,使用FPGA编译软件所带的编辑器写代码已经完全够用,但随着工程的不断增大,ISE自带的编辑器用起来显得有点力不从心,所以本文中我将为大家分享一款功能强大的编辑软件UltraEd ...

  9. chrome浏览器打开网页,总是跳转到2345主页的解决方法 2345.com 绑架主页

    昨晚装了一个wifi共享精灵,原本以为这下好了,全宿舍都可以上网了,但是,确实噩梦的开始啊. 遇到问题:不小心在安装wifi共享精灵的时候,点到了设置2345.com为主页,后来,每次使用chrome ...

  10. jQuery 实现上下,左右滑动

    前几天的任务:http://t.sina.com.cn/  的下滑效果. 渐变移动出足够的空白 -> 淡出最后一个 ->渐变移动出足够的空白 我们要做的是向左移动效果.这个效果用时需添加一 ...