BZOJ3192: [JLOI2013]删除物品(splay)
Description
Input
Output
Sample Input
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)的更多相关文章
- [bzoj3192][JLOI2013]删除物品(树状数组)
3192: [JLOI2013]删除物品 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 872 Solved: 508[Submit][Status ...
- [bzoj3192][JLOI2013]删除物品_树状数组_栈
删除物品 bzoj-3192 JLOI-2013 题目大意:给你n个物品,分成2堆.所有的物品有不同的优先级.我只可以将一堆中的堆顶移动到另一个堆的堆顶.而如果当前物品是全局所有物品中优先级最高的,我 ...
- bzoj3192 [JLOI2013]删除物品
用数组表示两个栈,将两个栈的栈顶并在一起,用树状数组维护一下操作即可. 代码 #include<cstdio> #include<algorithm> #include< ...
- bzoj3192: [JLOI2013]删除物品(树状数组)
既然要从一个堆的堆顶按顺序拿出来放到第二个堆的堆顶,那么我们就可以把两个堆顶怼在一起,这样从一个堆拿到另一个堆只需要移动指针就好了. 换句话说,把1~n倒着,n+1到n+m正着,用一个指针把两个序列分 ...
- 洛谷 P3253 [JLOI2013]删除物品 解题报告
P3253 [JLOI2013]删除物品 题目描述 箱子再分配问题需要解决如下问题: (1)一共有\(N\)个物品,堆成\(M\)堆. (2)所有物品都是一样的,但是它们有不同的优先级. (3)你只能 ...
- 3192: [JLOI2013]删除物品
3192: [JLOI2013]删除物品 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1366 Solved: 794 [Submit][Statu ...
- BZOJ3192:[JLOI2013]删除物品——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=3192 箱子再分配问题需要解决如下问题: (1)一共有N个物品,堆成M堆. (2)所有物品都是一样的 ...
- bzoj 3192: [JLOI2013]删除物品
Description 箱子再分配问题需要解决如下问题: (1)一共有N个物品,堆成M堆. (2)所有物品都是一样的,但是它们有不同的优先级. (3)你只能够移动某堆中位于顶端的物品. ( ...
- [JLOI2013]删除物品
嘟嘟嘟 只要每一次将优先级最高的上面的物品移走,就一定能保证是最优解. 所以我们只要想办法简化这个模拟移物品的过程,看完了题解后,发现可以这么想,我们可以把两个栈头碰头的挨在一起,然后设一个指针代表两 ...
随机推荐
- UVa 11085 - Back to the 8-Queens
题目:给你一个棋盘上的八个皇后.每行一个.如今让他们互相不攻击,每一个皇后仅仅能竖着移动, 一次能够移动到本列的不论什么位置,问最少移动几步.能满足要求. 分析:搜索,八皇后.由于八皇后仅仅有92组解 ...
- To new is C++; To malloc is C; To mix them is sin (混淆C++中的new和C中的malloc是一种犯罪)
Introduction One of the most common questions that get asked during interviews for C++ programmers i ...
- JS学习十七天----工厂方法模式
工厂方法模式 前言 今天自己看了一下自己写的部分博客,发现写的好丑....開始注意自己的排版!!可是偏亮也不是一朝一夕就完毕的,我尽量让它美丽一点.....每天美丽一点点 正文 工厂方法模式是一种实现 ...
- 轻松掌握Ubuntu Linux的3D桌面快捷键使用
视频下载地址: http://115.com/file/be4n23v6#linux3d.rar 轻松掌握Ubuntu Linux的3D桌面快捷键使用 高级3D桌面展示 本文出自 "李晨光原 ...
- Servlet之doPost获取表单参数
/** * 获取表单参数 */ private void readForm() { // TODO Auto-generated method stub Enumeration e = request ...
- Win7+MSVC2010+PCL1.7.2
我的配置环境是Win7+MSVC2010+PCL1.7.2. 网上关于点云库配置的文章已经很多,这里不做过多的重复,这里只讲一下自己在配置过程中遇到的问题及一些注意事项. K1: 在用Cmake编译时 ...
- Android开发当中Parcelable接口的使用
本文转载于:http://www.2cto.com/kf/201205/132814.html 本文稍微做了些修改 android提供了一种新的类型:Parcel.本类被用作封装数据的容器,封装后的数 ...
- 通用查询实现方案(可用于DDD)[附源码] -- 简介
原文:通用查询实现方案(可用于DDD)[附源码] -- 简介 [声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3985353.html). [ ...
- cogs 1500. 误差曲线
1500. 误差曲线 ★★ 输入文件:errorcurves.in 输出文件:errorcurves.out 评测插件时间限制:1 s 内存限制:256 MB [题目描述] Josep ...
- Nginx模型 & 惊群问题
这篇写的不错 http://www.cnblogs.com/linguoguo/p/5511293.html Nginx为啥性能高-多进程异步IO模型 1. 对于每个worker进程来说,独立的进程, ...