SPOJ - QMAX3VN 一个动态的序列 ,在线询问某个区间的最大值。关于静态序列的区间最值问题,用ST表解决,参考POJ 3264

乍一看上去 splay可以轻松解决。书上说可以用块状链表解决,也没说具体怎么做。我也想不出来。

直接给splay代码吧,比较裸,这道题常数卡的有点紧,要注意优化。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=400000,h=1e+9; int Root,n,m;
struct Node
{
int val,cnt,size;
bool rev;
int father;int lson;int rson; int hei;int hest;
Node(int v,int height,int c,int fa,int l,int r)
{this->val=v;this->hei=height;this->hest=height;this->cnt=c;this->father=fa;this->lson=l;this->rson=r;rev=false;}
}tren[maxn]=Node(0,0,0,0,0,0); queue<int> memq; int newnode()
{
int loc=memq.front();memq.pop();
return loc;
} void dele(int loc)
{
memq.push(loc);
return ;
} void pushdown(int x)
{
if(x==0)return ;
if(tren[x].rev)
{
tren[x].rev=false;
swap(tren[x].lson,tren[x].rson);
if(tren[x].lson!=0)tren[tren[x].lson].rev=!tren[tren[x].lson].rev;
if(tren[x].rson!=0)tren[tren[x].rson].rev=!tren[tren[x].rson].rev;
}
} void update(int x)
{
tren[x].size=tren[x].cnt;
tren[x].hest=tren[x].hei;
if(tren[x].lson!=0){tren[x].size+=tren[tren[x].lson].size;tren[x].hest=max(tren[x].hest,tren[tren[x].lson].hest);}
if(tren[x].rson!=0){tren[x].size+=tren[tren[x].rson].size;tren[x].hest=max(tren[x].hest,tren[tren[x].rson].hest);}
} void zig(int x)
{
int fa=tren[x].father;
pushdown(fa);pushdown(x);
if(tren[tren[fa].father].lson==fa){tren[tren[fa].father].lson=x;}
else {tren[tren[fa].father].rson=x;}
tren[x].father=tren[fa].father;
tren[fa].father=x;
tren[fa].lson=tren[x].rson;
tren[tren[x].rson].father=fa;
tren[x].rson=fa;
update(tren[x].rson);update(x);//update(tren[x].father);
//swap(tren[fa],tren[x]);
} void zag(int x)
{
int fa=tren[x].father;
pushdown(fa);pushdown(x);
if(tren[tren[fa].father].lson==fa){tren[tren[fa].father].lson=x;}
else {tren[tren[fa].father].rson=x;}
tren[x].father=tren[fa].father;
tren[fa].father=x;
tren[fa].rson=tren[x].lson;
tren[tren[x].lson].father=fa;
tren[x].lson=fa;
update(tren[x].lson);update(x);//update(tren[x].father);
//swap(tren[fa],tren[x]);
} void splay(int root,int now)//核心
{
if(root==0||now==0)return ;
int end=tren[root].father;
while(tren[now].father!=end)
{
if(tren[now].father==root)
{
if(tren[tren[now].father].lson==now)zig(now);
else zag(now);
return ;
}
int fa=tren[now].father;int grand=tren[fa].father;
if(tren[grand].lson==fa)
{
if(tren[fa].lson==now){zig(fa);zig(now);continue;}
else{zag(now);zig(now);continue;}
}
else{
if(tren[fa].rson==now){zag(fa);zag(now);continue;}
if(tren[fa].lson==now){zig(now);zag(now);continue;}
}
}
return ;
} int insert(int fa,int root,int value)
{
int ans;
pushdown(root);
if(root==0)
{
root=newnode();
tren[root]=Node(value,0,1,fa,0,0);
update(root);
ans= root;
//splay(1,root);
}
if(tren[root].val==value)
{tren[root].cnt++;update(root);ans=0;}
if(tren[root].val>value)
{
if(tren[root].lson==0)
{
tren[root].lson=newnode();
tren[tren[root].lson]=Node(value,0,1,root,0,0);
update(tren[root].lson);
// splay(1,tren[root].lson);
ans= tren[root].lson;
}
else ans= insert(root,tren[root].lson,value);
}
else
{
if(tren[root].rson==0)
{
tren[root].rson=newnode();
tren[tren[root].rson]=Node(value,0,1,root,0,0);
update(tren[root].rson);
//splay(1,tren[root].rson);
ans= tren[root].rson;
}
else ans= insert(root,tren[root].rson,value);
}
update(root);
return ans;
} int access(int root,int key)
{
pushdown(root);
if(tren[root].val==key)return root;
if(tren[root].val<key)return access(tren[root].rson,key);
else return access(tren[root].lson,key);
} int Max(int root)
{
pushdown(root);
if(root==0||tren[root].rson==0)return root;
else return Max(tren[root].rson);
} int join(int l,int r)
{
if(l==0)return r;
if(r==0)return l;
int max=Max(l);
splay(l,max);
tren[max].rson=r;
return max;
} void erase(int root,int key)
{
int now=access(root,key);
int fa=tren[now].father;
if(tren[now].cnt>1){tren[now].cnt--;return ;}
else
{
if(tren[fa].lson==now){tren[fa].lson=join(tren[now].lson,tren[now].rson);}
else{tren[fa].rson=join(tren[now].lson,tren[now].rson);}
}
return ;
} int getKth(int root,int k)
{
while(root!=0&&k<=tren[root].size)
{
pushdown(root);
int ls=tren[root].lson,rs=tren[root].rson;
if(ls!=0&&k<=tren[ls].size){root=ls;continue;}
k-=tren[root].cnt;
if(ls!=0)k-=tren[ls].size;
if(k<=0){return root;}
root=rs;
}
} void maintain(int now,int val)
{
while(now!=0)
{
tren[now].size+=val;
now=tren[now].father;
}
}
vector<int>ans;
void print( int root)
{
if(root==0)return ;
pushdown(root);
print(tren[root].lson);
if(tren[root].val<=n&&tren[root].val>=1)ans.push_back(tren[root].val);
print(tren[root].rson);
} int main()
{freopen("t.txt","r",stdin);
//freopen("1.txt","w",stdout);
scanf("%d",&n);
int tot=3;
tren[1]=Node(0,-1,1,0,0,0);
Root=1;
tren[2]=Node(0,-1,1,0,0,0);
tren[1].rson=2;
tren[2].father=1;
update(2);update(1); int k=0;
for(int i=0;i<n;i++)
{
char c;int a,b,l,r;
scanf("%s%d%d",&c,&a,&b);
if(c=='A')
{
a+=h;
l=b;
r=b+1;
int klo=getKth(Root,l);
int klb,newson;
if(tren[klo].rson!=0)
{ klb=getKth(tren[klo].rson,1);
newson=tren[klb].lson=tot++; }else{ klb=klo; newson=tren[klb].rson=tot++;}
tren[newson]=Node(1,a,1,klb,0,0);
klo=newson;
while(klo!=0)
{
update(klo);
klo=tren[klo].father;
} splay(Root,newson);Root=newson;
}
if(c=='Q')
{
l=a;
r=b+2;
int klo=getKth(Root,l);
splay(Root,klo);Root=klo;
klo=getKth(Root,r);
splay(tren[Root].rson,klo);
printf("%d\n",tren[tren[klo].lson].hest-h);
//splay(Root,tren[klo].lson);Root=tren[klo].lson;
}
} return 0;
}

  

SPOJ - QMAX3VN (4350) splay的更多相关文章

  1. spoj 4487. Can you answer these queries VI (gss6) splay 常数优化

    4487. Can you answer these queries VI Problem code: GSS6 Given a sequence A of N (N <= 100000) in ...

  2. SPOJ 4487 Splay 基本操作

    插入操作,删除操作和置换操作都是单点的,所以不需要lazy标记.这个很简单,都是两次RotateTo,一次Splay操作就搞定. 求最大连续字段和的操作和线段树的题目类似,只需要保存最左边的连续最大字 ...

  3. SPOJ 4487. Can you answer these queries VI splay

    题目链接:点击打开链接 题意比較明显,不赘述. 删除时能够把i-1转到根,把i+1转到根下 则i点就在 根右子树 的左子树,且仅仅有i这一个 点 #include<stdio.h> #in ...

  4. SPOJ Query on a tree III (树剖(dfs序)+主席树 || Splay等平衡树)(询问点)

    You are given a node-labeled rooted tree with n nodes. Define the query (x, k): Find the node whose ...

  5. SPOJ GSS6 Can you answer these queries VI ——Splay

    [题目分析] 增加了插入和删除. 直接用Splay维护就好辣! 写了一个晚上,(码力不精),最后发现更新写挂了 [代码] #include <cstdio> #include <cs ...

  6. SPOJ 3273

    传送门: 这是一道treap的模板题,不要问我为什么一直在写模板题 依旧只放代码 Treap 版 //SPOJ 3273 //by Cydiater //2016.8.31 #include < ...

  7. SPOJ QTREE 系列解题报告

    题目一 : SPOJ 375 Query On a Tree http://www.spoj.com/problems/QTREE/ 给一个树,求a,b路径上最大边权,或者修改a,b边权为t. #in ...

  8. spoj 7258 Lexicographical Substring Search (后缀自动机)

    spoj 7258 Lexicographical Substring Search (后缀自动机) 题意:给出一个字符串,长度为90000.询问q次,每次回答一个k,求字典序第k小的子串. 解题思路 ...

  9. SPOJ QTREE4 lct

    题目链接 这个题已经处于花式tle了,改版后的spoj更慢了.. tle的话就多交几把... #include <iostream> #include <fstream> #i ...

随机推荐

  1. PHP 计数排序

    计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中. 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数. 算法描述 找出待排序的数组中 ...

  2. 【转】精选十二款餐饮、快递、票务行业微信小程序源码demo推荐

    微信小程序的初衷是为了线下实体业服务的,必须有实体相结合才能显示小程序的魅力.个人认为微信小程序对于餐饮业和快递业这样业务比较单一的行业比较有市场,故整理推荐12款餐饮业和快递业微信小程序源码demo ...

  3. jmeter录制火狐浏览器

    昨天看youtube,居然发现有这功能,啊哈哈 听不懂英语 也能有收获. 一.Jmeter 文件中选择Templates->Recording 二.创建之后,自动出现一个模板: 1. Threa ...

  4. Shiro_权限 URL 配置细节

    [部分细节] 1.[urls] 部分的配置,其格式是:“url=拦截器[参数],拦截器[参数]”: 2.如果当前请求的URL匹配 [urls] 部分的某个url模式,将会执行其配置的拦截器. 3.an ...

  5. maven使用nexus3.3在windows下搭建私服

    1. 私服简介 私服是指私有服务器,是架设在局域网的一种特殊的远程仓库,目的是代理远程仓库及部署第三方构建.有了私服之后,当 Maven 需要下载构件时,直接请求私服,私服上存在则下载到本地仓库:否则 ...

  6. COJ 1411 Longest Consecutive Ones

    题目大意: 希望在 k 步之内,将尽可能多的1移到相邻的位置上 这里依靠前缀和解决问题 我们用pos[i]保存第i个1的位置,这里位置我以1开始 用sum[i]保存前 i 个1从 0 点移到当前位置所 ...

  7. Mysql中Group By使用Having语句配合查询(where和having区别)

    注意 : having语句一般结合GROUP BY一起使用的..... Having短语与WHERE的区别!!! WHERE子句作用于基表或视图,从中选择满足条件的元组.HAVING短语作用于组,从中 ...

  8. 如何取消codeblocks对msvcr100.dll的依赖?

    用VS2010或是codeblocks开发的程序,在开发之外的机器上,可能会提前缺少msvcr100.dll之类的文件. 可以用如何设置,取消其对库文件的依赖. 当然,还要注意创建程序的类型.(补) ...

  9. [bzoj1597][USACO2008]土地购买(DP斜率优化/四边形优化)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1597 分析: 1.先可以把被包含的土地可以去掉,这些土地的长宽肯定都是不会用的,具体先 ...

  10. python实现汉诺塔算法

    汉诺塔 算法分析 1.步骤1:如果是一个盘子,直接将a柱子上的盘子从a移动到c 否则 2.步骤2:先将A柱子上的n-1个盘子借助C移动到B(图1) 已知函数形参为hanoi(n,a,b,c),这里调用 ...