Candy Collection

题意

有一串糖果箱,每个箱子有颜色,装有一定数量的糖果,然后现在要用大一点的条状箱子把它们运回去,每个条状箱子中装的是一段连续的箱子,不能有相同颜色的箱子,每个箱子的运费是所有箱子糖果数的按位或的和。求最小运费。

1 ≤ 1\leq 1箱子数量 ≤ 5 ∗ 1 0 5 \leq5*10^5 5105
1 ≤ 1\leq 1颜色 ≤ 1 0 6 \leq10^6 106
0 ≤ 0\leq 0糖果数 ≤ 1 0 6 \leq10^6 106

传送

传送

题解

d p [ i ] dp[i] dp[i]表示前i个箱子装完的最小代价,令 l m a x [ i ] l_{max}[i] lmax[i]表示最左边的一个位置,使得这个位置到 i i i都没有重复的颜色。那么有一个比较显然的dp方程 d p [ i ] = m i n   d p [ j − 1 ] + o r ( i , j )        ( l m a x [ i ] ≤ j ≤ i − 1 ) dp[i]=min \ dp[j-1]+or(i,j) \ \ \ \ \ \ (l_{max}[i]\leq j\leq i-1) dp[i]=min dp[j1]+or(i,j)      (lmax[i]ji1)
o r ( i , j ) = a i   o r   a i + 1   o r   ⋅ ⋅ ⋅   o r   a j or(i,j)=a_i \ or\ a_{i+1}\ or\ ···\ or\ a_j or(i,j)=ai or ai+1 or  or aj
然后显然时间复杂度是 O ( n 2 ) O(n^2) O(n2)的,考虑优化。

方法一

区间 m i n min min,上线段树。

然后就是从左往右遍历的时候这个 o r or or函数非常不好搞,按位拆开的话,总和的 m i n min min又不好求,但是我们发现我们始终维护的是一些右端点为 i i i的区间,这意味着,如果在 i i i之前有一个 a j a_j aj的第 b b b个二进制位是 1 1 1,那么 o r ( 1 , i ) , o r ( 2 , i ) , ⋅ ⋅ ⋅ , o r ( j , i ) or(1,i),or(2,i),···,or(j,i) or(1,i),or(2,i),,or(j,i)的第b个二进制位都是1,所以我们枚举当前糖果数量 V i V_i Vi的是1的二进制位,预处理 p r e [ i ] [ j ] pre[i][j] pre[i][j]表示i位置前最近的,第j个二进制位是1的数的位置,这个数组 O ( n log ⁡ V i ) O(n\log V_i) O(nlogVi)就可以处理完毕。然后我们就在线段树上的 [ p r e [ i ] [ b ] , i ] [pre[i][b],i] [pre[i][b],i]这个区间加上 2 b 2^b 2b,就可以实现维护。剩下的就很简单了,区间修改,区间查询最小值。时间复杂度 O ( n log ⁡ n log ⁡ V i ) O(n\log n\log V_i) O(nlognlogVi)

方法二

同样聚焦于这个or函数,因为or只有区间合并性,没有区间可减性,所以不能用前缀和,用st表 O ( n log ⁡ n ) O(n\log n) O(nlogn)预处理之后可以做到 O ( 1 ) O(1) O(1)计算 o r ( i , j ) or(i,j) or(i,j)。其次,考虑那一长串的or值 o r ( 1 , i ) , o r ( 2 , i ) , ⋅ ⋅ ⋅ or(1,i),or(2,i),··· or(1,i),or(2,i),其实不同的or值最多只有 O ( log ⁡ V i ) O(\log V_i) O(logVi)种,而如果 [ a , b ] [a,b] [a,b]这段区间的or值相同,那么我肯定取a转移是更优的。所以我做这么多次二分,找出那 log ⁡ V i \log V_i logVi个可转移的点,然后转移就行了。时间复杂度也是 O ( n log ⁡ n log ⁡ V i ) O(n\log n\log V_i) O(nlognlogVi)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值