BZOJ3192: [JLOI2013]删除物品(splay)
Description
箱子再分配问题需要解决如下问题:
(1)一共有N个物品,堆成M堆。
(2)所有物品都是一样的,但是它们有不同的优先级。
(3)你只能够移动某堆中位于顶端的物品。
(4)你可以把任意一堆中位于顶端的物品移动到其它某堆的顶端。若此物品是当前所有物品中优先级最高的,可以直接将之删除而不用移动。
(5)求出将所有物品删除所需的最小步数。删除操作不计入步数之中。
(6)只是一个比较难解决的问题,这里你只需要解决一个比较简单的版本:
不会有两个物品有着相同的优先级,且M=2
Input
第一行是包含两个整数N1,N2分别表示两堆物品的个数。
接下来有N1行整数按照从顶到底的顺序分别给出了第一堆物品中的优先级,数字越大,优先级越高。
再接下来的N2行按照同样的格式给出了第二堆物品的优先级。
Output
对于每个数据,请输出一个整数,即最小移动步数。
Sample Input
3 3
1
4
5
2
7
3
1
4
5
2
7
3
Sample Output
6
解题思路:
决策已经很明显了,找到最大的,把上面的压到另外一堆里。
考虑splay维护一下。
还要开long long.
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define lll tr[spc].ch[0] 5 #define rrr tr[spc].ch[1] 6 #define ls ch[0] 7 #define rs ch[1] 8 using std::swap; 9 const int N=1000000; 10 typedef long long lnt; 11 struct data{ 12 lnt Max_val; 13 lnt Where_is_Max_Val; 14 bool friend operator < (data x,data y) 15 { 16 return x.Max_val<y.Max_val; 17 } 18 lnt wp() 19 { 20 return Where_is_Max_Val; 21 } 22 }; 23 struct trnt{ 24 int ch[2]; 25 int fa; 26 int lzt; 27 lnt val; 28 data mxs; 29 lnt wgt; 30 }tr[N]; 31 int siz; 32 int n1,n2; 33 int root1,root2; 34 int fst1,lst1; 35 int fst2,lst2; 36 lnt ans=0; 37 lnt num[N]; 38 data max(data a,data b) 39 { 40 if(a.Max_val<b.Max_val) 41 return b; 42 return a; 43 } 44 bool whc(int spc) 45 { 46 return tr[tr[spc].fa].rs==spc; 47 } 48 void res(int spc) 49 { 50 tr[spc].wgt=1; 51 tr[spc].mxs=(data){tr[spc].val,spc}; 52 return ; 53 } 54 void pushup(int spc) 55 { 56 res(spc); 57 if(lll) 58 { 59 tr[spc].wgt+=tr[lll].wgt; 60 tr[spc].mxs=max(tr[spc].mxs,tr[lll].mxs); 61 } 62 if(rrr) 63 { 64 tr[spc].wgt+=tr[rrr].wgt; 65 tr[spc].mxs=max(tr[spc].mxs,tr[rrr].mxs); 66 } 67 return ; 68 } 69 void trr(int spc) 70 { 71 if(!spc) 72 return ; 73 tr[spc].lzt^=1; 74 swap(lll,rrr); 75 return ; 76 } 77 void pushdown(int spc) 78 { 79 if(tr[spc].lzt) 80 { 81 trr(lll); 82 trr(rrr); 83 tr[spc].lzt=0; 84 } 85 return ; 86 } 87 void recal(int spc) 88 { 89 if(tr[spc].fa) 90 recal(tr[spc].fa); 91 pushdown(spc); 92 return ; 93 } 94 void rotate(int spc) 95 { 96 int f=tr[spc].fa; 97 bool k=whc(spc); 98 tr[f].ch[k]=tr[spc].ch[!k]; 99 tr[spc].ch[!k]=f; 100 tr[tr[f].fa].ch[whc(f)]=spc; 101 tr[spc].fa=tr[f].fa; 102 tr[f].fa=spc; 103 tr[tr[f].ch[k]].fa=f; 104 pushup(f); 105 pushup(spc); 106 return ; 107 } 108 int splay(int spc,int f) 109 { 110 recal(spc); 111 while(tr[spc].fa!=f) 112 { 113 int ft=tr[spc].fa; 114 if(tr[ft].fa==f) 115 { 116 rotate(spc); 117 break; 118 } 119 if(whc(spc)^whc(ft)) 120 rotate(spc); 121 else 122 rotate(ft); 123 rotate(spc); 124 } 125 return spc; 126 } 127 void build(int &spc,int l,int r,int f) 128 { 129 if(l>r) 130 return ; 131 spc=++siz; 132 int mid=(l+r)>>1; 133 tr[spc].fa=f; 134 tr[spc].val=num[mid]; 135 res(spc); 136 build(lll,l,mid-1,spc); 137 build(rrr,mid+1,r,spc); 138 pushup(spc); 139 return ; 140 } 141 int fstfind(int spc) 142 { 143 while(lll) 144 spc=lll; 145 return spc; 146 } 147 int lstfind(int spc) 148 { 149 while(rrr) 150 spc=rrr; 151 return spc; 152 } 153 int maxmin(int spc) 154 { 155 pushdown(spc); 156 spc=lll; 157 pushdown(spc); 158 while(rrr) 159 { 160 spc=rrr; 161 pushdown(spc); 162 } 163 return spc; 164 } 165 int minmax(int spc) 166 { 167 pushdown(spc); 168 spc=rrr; 169 pushdown(spc); 170 while(lll) 171 { 172 spc=lll; 173 pushdown(spc); 174 } 175 return spc; 176 } 177 int lstmax(int spc) 178 { 179 pushdown(spc); 180 if(lll) 181 return maxmin(spc); 182 recal(spc); 183 while(whc(spc)==0) 184 spc=tr[spc].fa; 185 return tr[spc].fa; 186 } 187 int main() 188 { 189 scanf("%d%d",&n1,&n2); 190 for(int i=1;i<=n1;i++) 191 scanf("%lld",&num[n1-i+1]); 192 build(root1,0,n1+1,0); 193 fst1=fstfind(root1); 194 lst1=lstfind(root1); 195 for(int i=1;i<=n2;i++) 196 scanf("%lld",&num[n2-i+1]); 197 build(root2,0,n2+1,0); 198 fst2=fstfind(root2); 199 lst2=lstfind(root2); 200 for(int i=1;i<=n1+n2;i++) 201 { 202 root1=splay(fst1,0); 203 splay(lst1,root1); 204 root2=splay(fst2,0); 205 splay(lst2,root2); 206 int spc1,spc2; 207 spc1=tr[tr[root1].rs].ls; 208 spc2=tr[tr[root2].rs].ls; 209 if(tr[spc1].mxs<tr[spc2].mxs) 210 { 211 root2=splay(tr[spc2].mxs.wp(),0); 212 splay(lst2,root2); 213 int tmp=tr[tr[root2].rs].ls; 214 tr[tr[root2].rs].ls=0; 215 pushup(tr[root2].rs); 216 pushup(root2); 217 ans+=tr[tmp].wgt; 218 trr(tmp); 219 int temp=root2; 220 root2=splay(maxmin(temp),0); 221 splay(minmax(temp),root2); 222 tr[tr[root2].rs].ls=0; 223 pushup(tr[root2].rs); 224 pushup(root2); 225 root1=splay(lstmax(lst1),0); 226 splay(lst1,root1); 227 tr[tr[root1].rs].ls=tmp; 228 tr[tmp].fa=tr[root1].rs; 229 pushup(tr[root1].rs); 230 pushup(root1); 231 }else{ 232 root1=splay(tr[spc1].mxs.wp(),0); 233 splay(lst1,root1); 234 int tmp=tr[tr[root1].rs].ls; 235 tr[tr[root1].rs].ls=0; 236 pushup(tr[root1].rs); 237 pushup(root1); 238 ans+=tr[tmp].wgt; 239 trr(tmp); 240 int temp=root1; 241 root1=splay(maxmin(temp),0); 242 splay(minmax(temp),root1); 243 tr[tr[root1].rs].ls=0; 244 pushup(tr[root1].rs); 245 pushup(root1); 246 root2=splay(lstmax(lst2),0); 247 splay(lst2,root2); 248 tr[tr[root2].rs].ls=tmp; 249 tr[tmp].fa=tr[root2].rs; 250 pushup(tr[root2].rs); 251 pushup(root2); 252 } 253 } 254 printf("%lld\n",ans); 255 return 0; 256 }