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 }