首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

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

2013-02-06 
Splay解决区间问题[单点更新,区间最值询问]/*http://acm.hdu.edu.cn/showproblem.php?pid1754*//*单点更

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

/*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)>>1public:    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;}

热点排行