BZOJ3838 : [Pa2013]Raper
将选取的$A$看成左括号,$B$看成右括号,那么答案是一个合法的括号序列。
那么只要重复取出$k$对价值最小的左右括号,保证每时每刻都是一个合法的括号序列即可。
将$($看成$1$,$)$看成$-1$,设$s[]$为前缀和。
如果当前取出的是$()$,那么对前缀和的影响为$[A,B-1]$区间加$1$。
如果当前取出的是$)($,那么对前缀和的影响为$[B,A-1]$区间减$1$,所以这种情况需要满足区间$s$的最小值不为$0$。
考虑用线段树维护这个序列,线段树上每个节点维护以下信息:
va:$A\leq B$情况的最优解。
vb:$A>B$情况的最优解,且满足$[A,B-1]$的区间$s$最小值大于当前区间的$s$最小值。
vc:$A>B$情况的最优解。
aa:区间内代价最小的$A$。
ab:区间内代价最小的$B$。
ba:区间内代价最小的$A$,满足$[st,A-1]$的区间$s$最小值大于区间$s$最小值。
bb:区间内代价最小的$B$,满足$[B,en]$的区间$s$最小值大于区间$s$最小值。
vm:区间$s$最小值。
tag:区间增量标记。
为了方便维护,可以考虑增加第$0$项,$A[0]=B[0]=inf$。
那么$[0,n]$区间的$vb$必定满足区间最小值不为$0$,然后贪心选取$k$次即可求出最优解。
时间复杂度$O(k\log n)$。
#include<cstdio>
const int N=500010,M=1050000,inf=1000000010;
long long ans;
int n,k,i,j,A[N],B[N],aa[M],ab[M],ba[M],bb[M],vm[M],tag[M];
struct P{
int x,y;
P(){}
P(int _x,int _y){x=_x,y=_y;}
P operator+(const P&b){return A[x]+B[y]<A[b.x]+B[b.y]?*this:b;}
}va[M],vb[M],vc[M],t;
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
inline void add1(int x,int p){vm[x]+=p;tag[x]+=p;}
inline void pb(int x){if(tag[x])add1(x<<1,tag[x]),add1(x<<1|1,tag[x]),tag[x]=0;}
inline void up(int x){
int l=x<<1,r=l|1;
va[x]=va[l]+va[r]+P(aa[l],ab[r]);
vc[x]=vc[l]+vc[r]+P(aa[r],ab[l]);
vb[x]=vb[l]+vb[r];
aa[x]=A[aa[l]]<A[aa[r]]?aa[l]:aa[r];
ab[x]=B[ab[l]]<B[ab[r]]?ab[l]:ab[r];
if(vm[l]<vm[r]){
vb[x]=vb[x]+vc[r]+P(aa[r],bb[l]);
ba[x]=ba[l];
bb[x]=B[ab[r]]<B[bb[l]]?ab[r]:bb[l];
vm[x]=vm[l];
}
if(vm[l]>vm[r]){
vb[x]=vb[x]+vc[l]+P(ba[r],ab[l]);
ba[x]=A[aa[l]]<A[ba[r]]?aa[l]:ba[r];
bb[x]=bb[r];
vm[x]=vm[r];
}
if(vm[l]==vm[r]){
vb[x]=vb[x]+P(ba[r],bb[l]);
ba[x]=ba[l];
bb[x]=bb[r];
vm[x]=vm[l];
}
}
void build(int x,int a,int b){
if(a==b){
va[x]=vc[x]=P(a,a),vb[x]=P(0,0);
aa[x]=ab[x]=ba[x]=a;
return;
}
int mid=(a+b)>>1;
build(x<<1,a,mid),build(x<<1|1,mid+1,b),up(x);
}
void add(int x,int a,int b,int c,int d,int p){
if(c<=a&&b<=d){add1(x,p);return;}
pb(x);
int mid=(a+b)>>1;
if(c<=mid)add(x<<1,a,mid,c,d,p);
if(d>mid)add(x<<1|1,mid+1,b,c,d,p);
up(x);
}
void change(int x,int a,int b,int c){
if(a==b)return;
pb(x);
int mid=(a+b)>>1;
if(c<=mid)change(x<<1,a,mid,c);else change(x<<1|1,mid+1,b,c);
up(x);
}
int main(){
read(n),read(k);
for(i=1;i<=n;i++)read(A[i]);
for(i=1;i<=n;i++)read(B[i]);
A[0]=B[0]=inf;
build(1,0,n);
while(k--){
t=va[1]+vb[1],i=t.x,j=t.y,ans+=A[i]+B[j];
if(i<j)add(1,0,n,i,j-1,1);
if(i>j)add(1,0,n,j,i-1,-1);
A[i]=inf,change(1,0,n,i);
B[j]=inf,change(1,0,n,j);
}
return printf("%lld",ans),0;
}
BZOJ3838 : [Pa2013]Raper的更多相关文章
- 题解 洛谷 P4694 【[PA2013]Raper】
首先考虑题目的性质,不难发现光盘的花费是一个凸函数.当生产 \(0\) 张光盘时,其花费为 \(0\),随着光盘生产数的增加,最优情况肯定是先选择工厂便宜的时刻,所以花费会增长越来越快,因此其为一个下 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- 【BZOJ3733】[Pa2013]Iloczyn (搜索)
[BZOJ3733][Pa2013]Iloczyn (搜索) 题面 BZOJ 题解 把约数筛出来之后,直接爆搜,再随便剪枝就过了. 最近一句话题解倾向比较严重 #include<iostream ...
- 【BZOJ3837】[Pa2013]Filary 随机化神题
[BZOJ3837][Pa2013]Filary Description 给定n个正整数,从中挑出k个数,满足:存在某一个m(m>=2),使得这k个数模m的余数相等. 求出k的最大值,并求出此时 ...
- 【BZOJ3837】[PA2013]Filary
[BZOJ3837][PA2013]Filary 题面 darkbzoj 题解 考虑到模数为\(2\)时答案至少为\(\frac n2\),这是我们答案的下界. 那么我们对于任意的一个数,它们答案集合 ...
- 【BZOJ】3737: [Pa2013]Euler
题意: 求满足\(phi(a)=n\)的\(a\)的个数.(\(n \le 10^{10}\)) 分析 这种题一开始就感觉是搜索= = 题解 首先容易得到 \[\phi(n) = \prod_{i} ...
- BZOJ 3736: [Pa2013]Karty
Description 一个0/1矩阵,求能覆盖所有 \(1\) ,同时不覆盖所有 \(0\) 的矩阵,使这个面积最大. Sol DP/悬线法. 首先,所求的矩阵一定可以覆盖所有贴边的悬线. 用悬线法 ...
- BZOJ3733 : [Pa2013]Iloczyn
首先将$n$的约数从小到大排序,设$dfs(x,y,z)$表示当前可以选第$x$个到第$m$个约数,还要选$y$个,之前选的乘积为$z$是否可能. 爆搜的时候,如果从$x$开始最小的$y$个相乘也超过 ...
- BZOJ3839 : [Pa2013]Działka
对于每个询问,首先可以通过扫描线+线段树求出四个方向的第一个点,询问范围等价于框住这些点的最小矩形. 对于一个点$i$,预处理出: $A[i][j]$:$i$往左下角按凸壳走到$j$时,凸壳上相邻两点 ...
随机推荐
- 在Linux用户空间做内核空间做的事情
导读 我相信,Linux 最好也是最坏的事情,就是内核空间(kernel space)和用户空间(user space)之间的巨大差别.如果没有这个区别,Linux 可能也不会成为世界上影响力最大的操 ...
- Delphi与C语言类型转换对照
When converting C function prototypes to Pascal equivalent declarations, it's important to substitut ...
- 18个网站SEO建议
第一位专家是Autotrader公司的搜索市场经理Dewi Nawasari,她认为SEO就是优化网站,以吸引你的目标客户的过程.她的建议如下: 1.创建良好的引导链接 要把用户的使用过程尽量的简化, ...
- ethtool 命令详解
命令描述: ethtool 是用于查询及设置网卡参数的命令. 使用概要:ethtool ethx //查询ethx网口基本设置,其中 x 是对应网卡的编号,如eth0.eth1等等 转自: ...
- 基础知识《零》---Java程序运行机制及运行过程
Java运行机制 Java虚拟机(Java Virtual Machine):Java虚拟机可以理解成一个以字节码为机器指令的CPU:对于不同的运行平台,有不同的虚拟机:Java虚拟机机制屏蔽了底层运 ...
- nested exception is org.xml.sax.SAXParseException; lineNumber: 8; columnNumber: 56; cvc-complex-type.2.4.c通配符的匹配很全面, 但无法找到元素 'dubbo:application' 的声明
严重: Exception sending context initialized event to listener instance of class org.springframework.we ...
- spring3.2.8+quartz2.2.0(比较全,对比quartz1.x的配置)
spring3.2.8 + quartz2.2.0报错: java.lang.IncompatibleClassChangeError: class org.springframework.sched ...
- schedule CCCallfunc CCCallfuncN CCCallfuncND
schedule(schedule_selector(HelloWorld::step), 1.0f); void HelloWorld::step(float dt) { CCLog("d ...
- iOS 中的字体预览
要预览iOS的各种字体的效果,可以访问http://iosfonts.com
- hdu 1233 还是畅通工程 解题报告
题目链接:http://code.hdu.edu.cn/showproblem.php?pid=1233 并查集的运用, 实质就是求最小生成树.先对所有的村庄距离从小到大排序,然后判断村庄之间是否属于 ...