hdu1754I Hate It(splay)

链接

线段树的水题,拿来学习一下splay.

本题涉及到求最大值以及单点更新,折腾了许久,差不多把splay搞明白了。

按位置建树,按位置是一颗排序二叉树,对于区间的操作非常方便,每次操作都将需要的结点转自根的右孩子的左孩子,因为加了2个结点,一个最小的,一个最大的,据说是为了防止越界。

这题只有单点,所以每次将所求结点旋自根节点即可。

  1 #include <iostream>

  2 #include<cstdio>

  3 #include<cstring>

  4 #include<algorithm>

  5 #include<stdlib.h>

  6 #include<vector>

  7 #include<cmath>

  8 #include<queue>

  9 #include<set>

 10 using namespace std;

 11 #define N 200010

 12 #define LL __int64

 13 #define INF 0xfffffff

 14 #define key_value ch[ch[root][1]][0]

 15 const double eps = 1e-8;

 16 const double pi = acos(-1.0);

 17 const double inf = ~0u>>2;

 18 int pre[N],s[N],size[N];

 19 int ch[N][2],a[N],val[N];

 20 int root,n,tot;

 21 void newnode(int &x,int k,int fa)

 22 {

 23     x = ++tot;

 24     ch[x][0]=ch[x][1] = 0;

 25     pre[x] = fa;

 26     size[x] = 1;

 27     s[x] = k;

 28     val[x] = k;

 29 }

 30 void pushup(int w)

 31 {

 32     size[w] = size[ch[w][0]]+size[ch[w][1]]+1;

 33     s[w] = max(max(s[ch[w][0]],s[ch[w][1]]),val[w]);

 34    // cout<<s[w]<<" "<<w<<"// "<<" "<<ch[w][1]<<" "<<s[w]<<endl;

 35 }

 36 void rotate(int r,int kind)

 37 {

 38     int y = pre[r];

 39     ch[y][!kind] = ch[r][kind];

 40     pre[ch[r][kind]] = y;

 41     if(pre[y])

 42     {

 43         ch[pre[y]][ch[pre[y]][1]==y] = r;

 44     }

 45     pre[r] = pre[y];

 46     ch[r][kind] = y;

 47     pre[y] = r;

 48     pushup(y);

 49     //pushup(r);

 50 }

 51 void splay(int r,int goal)

 52 {

 53     while(pre[r]!=goal)

 54     {

 55        if(pre[pre[r]]==goal)

 56         {

 57              rotate(r,ch[pre[r]][0]==r);

 58         }

 59         else

 60         {

 61             int y = pre[r];

 62             int kind = (ch[pre[y]][0]==y);

 63             if(ch[y][kind]==r)

 64             {

 65                 rotate(r,!kind);

 66                 rotate(r,kind);

 67             }

 68             else

 69             {

 70                 rotate(y,kind);

 71                 rotate(r,kind);

 72             }

 73         }

 74     }

 75     pushup(r);

 76     if(goal==0) root = r;

 77 }

 78 int get_k(int k)

 79 {

 80     int r = root;

 81     while(size[ch[r][0]]!=k)

 82     {

 83         if(size[ch[r][0]]>k)

 84         r = ch[r][0];

 85         else

 86         {

 87             k-=(size[ch[r][0]]+1);

 88             r = ch[r][1];

 89         }

 90     }

 91     return r;

 92 }

 93 int query(int l,int r)

 94 {

 95     splay(get_k(l-1),0);

 96     splay(get_k(r+1),root);

 97     return s[key_value];

 98 }

 99 /*void update(int l,int r,int k)

100 {

101     splay(get_k(l-1),0);

102     splay(get_k(r+1),root);

103     val[key_value] = k;

104     s[key_value] = k;

105     pushup(ch[root][1]);

106     pushup(root);

107 }*/

108 void update(int l,int r,int k)

109 {

110     int kk = get_k(l);

111     val[kk] = k;

112     splay(kk,0);

113 }

114 void build(int &w,int l,int r,int fa)

115 {

116     if(l>r) return ;

117     int m = (l+r)>>1;

118     newnode(w,a[m],fa);

119     build(ch[w][0],l,m-1,w);

120     build(ch[w][1],m+1,r,w);

121     pushup(w);

122 }

123 void init()

124 {

125     int i;

126     for(i = 0 ;i < n ;i++)

127     scanf("%d",&a[i]);

128     ch[0][0] = ch[0][1] = pre[0] = size[0] = s[0] = 0;

129     root = tot =0;

130     newnode(root,-1,0);

131     newnode(ch[root][1],-1,root);

132     size[root] = 2;

133     build(key_value,0,n-1,ch[root][1]);

134     pushup(ch[root][1]);

135     pushup(root);

136 }

137 int main()

138 {

139     int q,x,y,i;

140     char sq[10];

141     while(scanf("%d%d",&n,&q)!=EOF)

142     {

143         init();

144         while(q--)

145         {

146             scanf("%s%d%d",sq,&x,&y);

147             if(sq[0]=='U')

148             {

149                 update(x,x,y);

150                 /*for(i = 0; i <= n+2; i++)

151                 cout<<ch[i][0]<<" "<<ch[i][1]<<" "<<i<<endl;

152                 puts("");*/

153             }

154             else

155             {

156                 printf("%d\n",query(x,y));

157                 /*for(i = 0; i <= n+2; i++)

158                 cout<<ch[i][0]<<" "<<ch[i][1]<<" "<<i<<endl;

159                 puts("");*/

160             }

161         }

162     }

163     return 0;

164 }
View Code

 

你可能感兴趣的:(play)