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.

代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define lll tr[spc].ch[0]
#define rrr tr[spc].ch[1]
#define ls ch[0]
#define rs ch[1]
using std::swap;
const int N=;
typedef long long lnt;
struct data{
lnt Max_val;
lnt Where_is_Max_Val;
bool friend operator < (data x,data y)
{
return x.Max_val<y.Max_val;
}
lnt wp()
{
return Where_is_Max_Val;
}
};
struct trnt{
int ch[];
int fa;
int lzt;
lnt val;
data mxs;
lnt wgt;
}tr[N];
int siz;
int n1,n2;
int root1,root2;
int fst1,lst1;
int fst2,lst2;
lnt ans=;
lnt num[N];
data max(data a,data b)
{
if(a.Max_val<b.Max_val)
return b;
return a;
}
bool whc(int spc)
{
return tr[tr[spc].fa].rs==spc;
}
void res(int spc)
{
tr[spc].wgt=;
tr[spc].mxs=(data){tr[spc].val,spc};
return ;
}
void pushup(int spc)
{
res(spc);
if(lll)
{
tr[spc].wgt+=tr[lll].wgt;
tr[spc].mxs=max(tr[spc].mxs,tr[lll].mxs);
}
if(rrr)
{
tr[spc].wgt+=tr[rrr].wgt;
tr[spc].mxs=max(tr[spc].mxs,tr[rrr].mxs);
}
return ;
}
void trr(int spc)
{
if(!spc)
return ;
tr[spc].lzt^=;
swap(lll,rrr);
return ;
}
void pushdown(int spc)
{
if(tr[spc].lzt)
{
trr(lll);
trr(rrr);
tr[spc].lzt=;
}
return ;
}
void recal(int spc)
{
if(tr[spc].fa)
recal(tr[spc].fa);
pushdown(spc);
return ;
}
void rotate(int spc)
{
int f=tr[spc].fa;
bool k=whc(spc);
tr[f].ch[k]=tr[spc].ch[!k];
tr[spc].ch[!k]=f;
tr[tr[f].fa].ch[whc(f)]=spc;
tr[spc].fa=tr[f].fa;
tr[f].fa=spc;
tr[tr[f].ch[k]].fa=f;
pushup(f);
pushup(spc);
return ;
}
int splay(int spc,int f)
{
recal(spc);
while(tr[spc].fa!=f)
{
int ft=tr[spc].fa;
if(tr[ft].fa==f)
{
rotate(spc);
break;
}
if(whc(spc)^whc(ft))
rotate(spc);
else
rotate(ft);
rotate(spc);
}
return spc;
}
void build(int &spc,int l,int r,int f)
{
if(l>r)
return ;
spc=++siz;
int mid=(l+r)>>;
tr[spc].fa=f;
tr[spc].val=num[mid];
res(spc);
build(lll,l,mid-,spc);
build(rrr,mid+,r,spc);
pushup(spc);
return ;
}
int fstfind(int spc)
{
while(lll)
spc=lll;
return spc;
}
int lstfind(int spc)
{
while(rrr)
spc=rrr;
return spc;
}
int maxmin(int spc)
{
pushdown(spc);
spc=lll;
pushdown(spc);
while(rrr)
{
spc=rrr;
pushdown(spc);
}
return spc;
}
int minmax(int spc)
{
pushdown(spc);
spc=rrr;
pushdown(spc);
while(lll)
{
spc=lll;
pushdown(spc);
}
return spc;
}
int lstmax(int spc)
{
pushdown(spc);
if(lll)
return maxmin(spc);
recal(spc);
while(whc(spc)==)
spc=tr[spc].fa;
return tr[spc].fa;
}
int main()
{
scanf("%d%d",&n1,&n2);
for(int i=;i<=n1;i++)
scanf("%lld",&num[n1-i+]);
build(root1,,n1+,);
fst1=fstfind(root1);
lst1=lstfind(root1);
for(int i=;i<=n2;i++)
scanf("%lld",&num[n2-i+]);
build(root2,,n2+,);
fst2=fstfind(root2);
lst2=lstfind(root2);
for(int i=;i<=n1+n2;i++)
{
root1=splay(fst1,);
splay(lst1,root1);
root2=splay(fst2,);
splay(lst2,root2);
int spc1,spc2;
spc1=tr[tr[root1].rs].ls;
spc2=tr[tr[root2].rs].ls;
if(tr[spc1].mxs<tr[spc2].mxs)
{
root2=splay(tr[spc2].mxs.wp(),);
splay(lst2,root2);
int tmp=tr[tr[root2].rs].ls;
tr[tr[root2].rs].ls=;
pushup(tr[root2].rs);
pushup(root2);
ans+=tr[tmp].wgt;
trr(tmp);
int temp=root2;
root2=splay(maxmin(temp),);
splay(minmax(temp),root2);
tr[tr[root2].rs].ls=;
pushup(tr[root2].rs);
pushup(root2);
root1=splay(lstmax(lst1),);
splay(lst1,root1);
tr[tr[root1].rs].ls=tmp;
tr[tmp].fa=tr[root1].rs;
pushup(tr[root1].rs);
pushup(root1);
}else{
root1=splay(tr[spc1].mxs.wp(),);
splay(lst1,root1);
int tmp=tr[tr[root1].rs].ls;
tr[tr[root1].rs].ls=;
pushup(tr[root1].rs);
pushup(root1);
ans+=tr[tmp].wgt;
trr(tmp);
int temp=root1;
root1=splay(maxmin(temp),);
splay(minmax(temp),root1);
tr[tr[root1].rs].ls=;
pushup(tr[root1].rs);
pushup(root1);
root2=splay(lstmax(lst2),);
splay(lst2,root2);
tr[tr[root2].rs].ls=tmp;
tr[tmp].fa=tr[root2].rs;
pushup(tr[root2].rs);
pushup(root2);
}
}
printf("%lld\n",ans);
return ;
}

BZOJ3192: [JLOI2013]删除物品(splay)的更多相关文章

  1. [bzoj3192][JLOI2013]删除物品(树状数组)

    3192: [JLOI2013]删除物品 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 872  Solved: 508[Submit][Status ...

  2. [bzoj3192][JLOI2013]删除物品_树状数组_栈

    删除物品 bzoj-3192 JLOI-2013 题目大意:给你n个物品,分成2堆.所有的物品有不同的优先级.我只可以将一堆中的堆顶移动到另一个堆的堆顶.而如果当前物品是全局所有物品中优先级最高的,我 ...

  3. bzoj3192 [JLOI2013]删除物品

    用数组表示两个栈,将两个栈的栈顶并在一起,用树状数组维护一下操作即可. 代码 #include<cstdio> #include<algorithm> #include< ...

  4. bzoj3192: [JLOI2013]删除物品(树状数组)

    既然要从一个堆的堆顶按顺序拿出来放到第二个堆的堆顶,那么我们就可以把两个堆顶怼在一起,这样从一个堆拿到另一个堆只需要移动指针就好了. 换句话说,把1~n倒着,n+1到n+m正着,用一个指针把两个序列分 ...

  5. 洛谷 P3253 [JLOI2013]删除物品 解题报告

    P3253 [JLOI2013]删除物品 题目描述 箱子再分配问题需要解决如下问题: (1)一共有\(N\)个物品,堆成\(M\)堆. (2)所有物品都是一样的,但是它们有不同的优先级. (3)你只能 ...

  6. 3192: [JLOI2013]删除物品

    3192: [JLOI2013]删除物品 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1366 Solved: 794 [Submit][Statu ...

  7. BZOJ3192:[JLOI2013]删除物品——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3192 箱子再分配问题需要解决如下问题: (1)一共有N个物品,堆成M堆. (2)所有物品都是一样的 ...

  8. bzoj 3192: [JLOI2013]删除物品

    Description   箱子再分配问题需要解决如下问题:  (1)一共有N个物品,堆成M堆.  (2)所有物品都是一样的,但是它们有不同的优先级.  (3)你只能够移动某堆中位于顶端的物品.  ( ...

  9. [JLOI2013]删除物品

    嘟嘟嘟 只要每一次将优先级最高的上面的物品移走,就一定能保证是最优解. 所以我们只要想办法简化这个模拟移物品的过程,看完了题解后,发现可以这么想,我们可以把两个栈头碰头的挨在一起,然后设一个指针代表两 ...

随机推荐

  1. 百度LBS开放平台个性化地图 制作一款独一无二的地图

    百度LBS开放平台个性化地图  制作一款独一无二的地图 天天用百度地图的亲们是否已不再满足仅仅看例如以下的地图样式了呢? 默认百度地图样式 是否特别渴望看特别不一样的地图呢.如带京城81号气息的午夜蓝 ...

  2. 12.ng-switch

    转自:https://www.cnblogs.com/best/tag/Angular/ 根据作用域表达式动态切换把那个DOM元素包含在已经编译的模板中. 示例代码: <!DOCTYPE htm ...

  3. Js怎么获取DOM及获取浏览器的宽高?

    在JavaScript中,经常会需要获取document文档元素,是HTML文档对象模型的缩写,HTML DOM 定义了用于 HTML 的一系列标准的对象,以及访问和处理 HTML 文档的标准方法. ...

  4. Javascript 模块化理解

    原始时代: script标签引入javascript文件 -------- html ------- <div id="result"></div> < ...

  5. JS之闭包详细解读

    闭包在红宝书中的解释就是:有权访问另一个函数作用域中的变量的函数. 1.变量作用域 全局变量:所有的函数外部定义的变量,它的作用域是整个script. 局部变量:定义在函数体内部的变量,作用域仅限于函 ...

  6. jni中调用java方法获取当前apk的签名文件md5值

    相应的java方法: void getsign(Context context) throws Exception { PackageInfo localPackageInfo = context.g ...

  7. UI标签库专题九:JEECG智能开发平台 Choose(选则操作标签)

     1. Choose(选则操作标签) 1.1. 參数 属性名 类型 描写叙述 是否必须 默认值 hiddenName string 隐藏域的ID 否 null hiddenid string 隐藏 ...

  8. Greenplum中定义数据库对象之创建与管理模式

    创建与管理模式 概述:DB内组织对象的一种逻辑结构.一个DB内能够有多个模式.在未指定模式时默认放置在public中.能够通过"\dn"方式查看数据库中现有模式. testdw=# ...

  9. PHP CLI模式下的多进程应用分析

    PHP在非常多时候不适合做常驻的SHELL进程, 他没有专门的gc例程, 也没有有效的内存管理途径. 所以假设用PHP做常驻SHELL, 你会常常被内存耗尽导致abort而unhappy 并且, 假设 ...

  10. 简单说一下 JSON和JSONP

    JSON和JSONP,但从缩写看,可能会以为他们是很相似的两个名词,但他们除了缩写相似外,他们是两种类型的概念. 首先: JSON(JavaScript Object Notation)即JavaSc ...