北京Day 24

这篇博客详细解析了四道算法竞赛题目,涉及众数出现次数的区间问题、节点选择最大价值优化、楼梯数字计数以及树上路径交集的求解。通过二分、线段树、分组背包和函数式线段树等数据结构和算法,阐述了解题思路和解决方案。
摘要由CSDN通过智能技术生成

最后一天了。

T1

题目大意:定义一个区间的值为其众数出现的次数,给出n个数,求将所有区间的值排序后,第K大的值为多少。n<=1e5。

题解:

二分答案t,统计众数出现次数大于等于t的区间有多少个。

枚举右端点R,计算左端点L最大为多少,使得区间[L,R]的值大于等于t,对于每个R他对答案贡献为L。

通过线性扫一遍找出每一个数的前面第t-1个与他相同的数字,记其位置为b[i],若不存在则为0。

若R增加,则[L,R+1]的值也必定大于等于t,所以新的L=max(L,b[R+1]),这样就可以找出每一个R对应的L,计算出答案。

T2

题目大意:n个节点,选择每一个节点有代价,m个区间,区间内所有点都被选择有收益,令收益-代价最大。n,m<=2e5。

题解:

定义dp[i][j](1<=i<=j)表示当前考虑到第j个点时,刚好取了[i,j]这一段区间的点,所能得到的最大价值。

定义a[j]表示当前考虑到第j个点时,不选择第j个点,所能得到的最大价值。

状态转移方程如下:

a[j]=max(dp[1][j-1],dp[2][j-1]...dp[j-1][j-1],a[j-1]);         dp[j][j]=a[j-1]-cost[j];                dp[i][j]=dp[i][j-1]-cost[j]; (i<j).

如果有一段区间[L,R]的回报是W,则 dp[L][R]+=W, dp[L-1][R]+=W.... dp[1][R]+=W;

注意到状态转移的特性,所以可以用线段树来优化DP。

将线段树的叶子节点当作dp方程的第一维,那么以上即可变为区间加减,区间询问最值。

T3

题目大意:定义一个数是楼梯数字,当且仅当这个数的每一位数字不小于它的下一位数字。求有多少个长度恰好为n的楼梯数字,是k的倍数。由于数量很大,输出Mod 1000000007的结果。n<=1e8,k<=500。

题解:

楼梯数字可以拆成不超过 9 个全一数字的和,这些数字在模 K 意义下的值有 O(K) 种取值,可以将这些数分成 O(K) 组,进行分组背包计数。

令 f[i][j][k]表示前 i 组里选 j 个数的和在模 K 意义下是 k 的方案数,由于同一组里选 m 个数组成可重集的方案数是C(X−1+m,m),其中 X表示组里不同数字的个数,所以转移是枚举当前组里选多少个数进行转移。

注意 10^(N−1) /9至少要选1个,所以将它从上面的计数里排除,最后枚举它的数量,再配合之前计数的结果进行计数即可。

T4

题目大意:给定一棵n个点的树,以及m条路径,定义f(i,j)为第i条到第j条路径的交集部分的长度,求Σf(i,j)。n<=5e5。

题解:

考虑一条边会在多少个f(i,j)中被计算

当一条边断开后形成的两部分中,每个部分都含有一个第i~j条路径的端点,则f(i,j)中会包含这条边

所以可以枚举边后,计算其子树中有多少个f(i,j)符合条件,即第i~j条路径都有且仅有一个路径端点在该子树中

可以用函数式线段树来维护每棵子树的信息,对于表示点u子树的线段树,可以通过所有点u的儿子节点v的线段树合并得来

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值