HDU 1754 I Hate It (Splay 区间操作)

题目大意

维护一个序列,支持两种操作
操作一:将第x个元素的值修改为y
操作二:询问区间【x,y】内的元素的最大值

解题分析

splay的区间操作,事先加入两个编号最小和最大的点防止操作越界。
具体的区间操作类似于线段树。

参考程序

#include <bits/stdc++.h>
using namespace std;
const int INF=2000000000;
const int N=200008;
int a[N];

class splay_tree
{
public:
    struct node
    {
        int id,val,mx;
        node *l,*r,*f;
        node(int _id=0,int _val=0,int _mx=0,node *_f=NULL,node *_l=NULL,node *_r=NULL):
        mx(_mx),id(_id),val(_val),f(_f),l(_l),r(_r){}
    }*rt;
    void pushup(node *x)
    {
    	node *l=x->l,*r=x->r;
    	x->mx=x->val;
    	if (l) x->mx=max(x->mx,l->mx);
    	if (r) x->mx=max(x->mx,r->mx);
    }
    void right(node *x,node *&rt)
    {
        node *y=x->f,*z=y->f;
        if (y==rt) rt=x; else if (y==z->l) z->l=x; else z->r=x;
        if (x->r) x->r->f=y; y->f=x; x->f=z;
        y->l=x->r; x->r=y;
        pushup(y); pushup(x);
    }
    void left(node *x,node *&rt)
    {
        node *y=x->f,*z=y->f;
        if (y==rt) rt=x; else if (y==z->l) z->l=x; else z->r=x;
        if (x->l) x->l->f=y; y->f=x; x->f=z;
        y->r=x->l; x->l=y;
        pushup(y); pushup(x);
    }
    void splay(node *x,node *&rt)
    {
        while (x!=rt)
        {
            node *y=x->f,*z=y->f;
            if (y==rt) if (x==y->l) right(x,rt); else left(x,rt); 
            else if (y==z->l) if (x==y->l) {right(y,rt);right(x,rt);} else {left(x,rt);right(x,rt);} 
                 else if (x==y->r) {left(y,rt);left(x,rt);} else {right(x,rt);left(x,rt);}
        }
    }
    void del(node *rt)
    {
    	if (!rt) return;
    	del(rt->l);
    	del(rt->r);
    	delete rt;
    }
    splay_tree(){rt=NULL;}
    ~splay_tree()
    {
    	del(rt);
    }
    void build(int l,int r,node *&x,node *f)
    {
    	if (l>r) return;
    	int m=l+r>>1;
    	x=new node(m,a[m],a[m],f);
    	if (l==r) return;
    	build(l,m-1,x->l,x);
    	build(m+1,r,x->r,x);
    	pushup(x);
    }
    void find(int id,node* &rt)
    {	
    	node *x=rt;
    	while (x->id!=id)
    	{
    		if (id<x->id) x=x->l; else x=x->r;
    	}
    	splay(x,rt);
    }
    void update(int id,int val)
    {	
    	node *x=rt;
    	while (x->id!=id)
    	{
    		if (id<x->id) x=x->l; else x=x->r;
    	}
    	x->val=val;
    	splay(x,rt);
    }
    int query(int x,int y)
    {
    	find(x-1,rt);
    	find(y+1,rt->r);
    	return rt->r->l->mx;
    }
    void visit(node *rt)
    {
    	if (!rt) return;
    	cout<<" id = "<<rt->id<<" val = "<<rt->val;
    	cout<<" lson = "<<(rt->l?rt->l->id:0);
    	cout<<" rson = "<<(rt->r?rt->r->id:0)<<endl;
    	visit(rt->l);
    	visit(rt->r);
    }
};
int main()
{
    cin.sync_with_stdio(0);
    int n,m;
    while (cin>>n>>m)
    {
    	splay_tree T;
    	for (int i=1;i<=n;i++) cin>>a[i];
    	a[0]=a[n+1]=0;
    	T.build(0,n+1,T.rt,NULL);	
    	for (int i=1;i<=m;i++) 
   	 	{
    		string s;int x,y;
    		cin>>s>>x>>y;
    		if (s[0]=='Q')
    			cout<<T.query(x,y)<<endl;
    		else
    			T.update(x,y);
  		}
	}
}
原文地址:https://www.cnblogs.com/rpSebastian/p/6804487.html