您的位置:首页 > 其它

Splay解决区间问题[单点更新,区间最值询问]

2013-01-31 21:20 477 查看
/*http://acm.hdu.edu.cn/showproblem.php?pid=1754*/
/*单点更新,区间询问 splay实现*/
/*注意写rotateTo的时候。。*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 222222;
class SplayTree{
#define l(x) (ch[x][0])
#define r(x) (ch[x][1])
#define mid(x,y) (x+y)>>1
public:
int ch[MAXN][2],pre[MAXN],sz[MAXN],mx[MAXN],val[MAXN],a[MAXN];
int root,tot;
void init(){
memset(ch,0,sizeof(int)*MAXN*2);
memset(pre,0,sizeof(int)*MAXN);
memset(sz,0,sizeof(int)*MAXN);
memset(mx,-1,sizeof(int)*MAXN);
root = tot = 0;
}
void read(int n){
a[1] = a[n+2] = -1;
for(int i=2;i<=n+1;i++) scanf("%d",&a[i]);
}
void push_up(int rt){
mx[rt] = max(max(mx[l(rt)],mx[r(rt)]),val[rt]);
sz[rt] = sz[l(rt)]+sz[r(rt)]+1;
}
void rotate(int x,int f){
int y = pre[x];
ch[y][!f] = ch[x][f];
if(ch[y][!f]) pre[ch[y][!f]] = y;
push_up(y);
if(pre[y]) ch[pre[y]][r(pre[y])==y] = x;
pre[x] = pre[y];
ch[x][f] = y;
pre[y] = x;
}
void splay(int x,int goal){
while(pre[x]!=goal){
int y = pre[x], z = pre[pre[x]];
if(z==goal){
rotate(x,l(y)==x);
}else{
int f = (l(z)==y);
if(ch[y][!f]==x){
rotate(y,f); rotate(x,f);
}else{
rotate(x,!f); rotate(x,f);
}
}
}
push_up(x);
if(goal==0) root = x;
}
void rotateTo(int x,int goal){
int k = root;
while(1){
if(x<(sz[l(k)]+1)) k = l(k);
else if(x==(sz[l(k)]+1)){
break;
}else{
x -= (sz[l(k)]+1);
k = r(k);
}
}
splay(k,goal);
}
void buildTree(int l,int r,int &rt,int f){
if(l>r)return;
int m = mid(l,r);
rt = ++tot;
val[rt] = a[m];
pre[rt] = f;
buildTree(l,m-1,l(rt),rt);
buildTree(m+1,r,r(rt),rt);
push_up(rt);
}
int query(int l,int r){
rotateTo(l-1,0);
rotateTo(r+1,root);
return mx[l(r(root))];
}
void update(int pos,int c){
rotateTo(pos,0);
val[root] = c;
push_up(root);
}
void debug(){
printf("root:%d l(root):%d r(root):%d\n",root,l(root),r(root));
dfs(root);
}
void dfs(int rt){
if(!rt)return;
dfs(l(rt));
printf("node:%d max:%d size:%d val:%d lson:%d rson:%d pre:%d\n",rt,mx[rt],sz[rt],val[rt],l(rt),r(rt),pre[rt]);
dfs(r(rt));
}
};
SplayTree spt;
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
spt.init();
spt.read(n);
spt.buildTree(1,n+2,spt.root,0);
char op[2]; int a,b;
while(m--){
scanf("%s%d%d",op,&a,&b);
//spt.debug(); system("pause");
if(op[0]=='Q'){
printf("%d\n",spt.query(a+1,b+1));
}else{
spt.update(a+1,b);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: