2017.07.11【NOIP提高组】模拟赛B组

T1:dp。

设f[i][j]表示从i到j的一段在一个月内完成的总共的最少月数(i<=j),那么我们需要枚举一个k,表示k到i-1的一段也在一个月内完成。于是就可以从f[k][i-1]转移到f[i][j]。

那么有以下两种情况:

1、若sum(b[l])+sum(a[r])<=m(k<=l<i)(i<=r<=j),那么f[i][j]=min(f[i][j],f[k][i-1]+1),这种情况表示的是两段可以在一个月内解决。

2、若sum(b[l])+sum(a[r])>m(k<=l<i)(i<=r<=j),那么f[i][j]=min(f[i][j],f[k][i-1]+2),这种情况表示的是两段不能在同一个月内完成,需要多加一个月来还债。

当然,要执行转移的前提条件都是sum(a[k~i-1])<=m&sum(b[k~i-1]<=m)&sum(a[i~j])<=m&sum(b[i~j])<=m。


T2:把RMQ用在树上。

设f[i][j]表示节点i向根走2^j的答案

p[i][j]表示节点i向根走2^j的最大值

g[i][j]表示节点i向根走2^j的最小值

fa[i][j]表示节点i的2^j级祖先(不包括i)

那么我们先dfs一遍求出fa,fa[i][j]=fa[fa[i][j-1]][j-1]。

然后dfs一遍求出p与g,p[i][j]=max(p[fa[i][j-1]][j-1],p[i][j-1]),g只需把max改成min就行了。

接着dfs一遍求出f,f[i][j]=max(f[fa[i][j-1]][j-1],f[i][j-1],p[fa[i][j-1]][j-1]-g[i][j-1])。

最后求ans。设输入的为x,y,那么我们用递归来做。

我们每次找出一个最大的k使得2^k<=y,然后用f[x][k]去更新ans,接着把y减去2^k,x改成fa[x][k],直到y=0为止。

有一个地方要注意,我们每次都要更新一个last,last表示为当前的最小值,last=min(last,g[x][y]),然后我们每次还要用p[x][y]-last来更新ans。


T3:我们先要发现一个性质,就是或运算的值不会减少。所以我们可以用线段树来维护或的值,然后枚举左端点,二分右端点,更新答案。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值