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

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 }

 

posted @ 2018-09-22 10:53  Unstoppable728  阅读(177)  评论(0编辑  收藏  举报