[BZOJ5286][Hnoi2018]转盘(线段树)

这篇博客探讨了如何使用线段树解决一个转盘问题。内容涉及到将原问题转化为寻找最小时间`t`和起始位置`x`,使得在`t`时刻从`x`开始,每步前进,满足在每个物品出现时已标记到该物品。通过分析得出,可以将问题简化为求解线性序列的前缀最大值,并利用线段树维护单调子序列,实现复杂度为`O(n log^2 n)`的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Address

洛谷 P4425
BZOJ 5286
LOJ #2495

Solution

  • 首先可以知道,选择逗留在原物品不会更优
  • 然后问题转化成
  • 选取一个 t t t ,并选取环上一物品 x x x ,在 t t t 时刻从 x x x 出发,每单位时间前进一步,要求如果经过的 i i i 个物品(出发处为第 0 0 0 个物品)出现时间为 k k k ,则需要满足 t + i ≥ k t+i\ge k t+ik (在出现时或之后才能标记到这个物品),求最小的 t t t ,答案即为 t min ⁡ + n − 1 t_{\min}+n-1 tmin+n1
  • 考虑将 T T T 数组复制一遍
  • 然后限制条件变成
  • ∀ x ≤ i ≤ x + n − 1 , t + i − x ≥ T i \forall x\le i\le x+n-1,t+i-x\ge T_i xix+n1,t+ixTi
  • 于是当 x x x 固定时
  • t = max ⁡ i = x x + n − 1 { T i − i } + x t=\max_{i=x}^{x+n-1}\{T_i-i\}+x t=i=xmaxx+n1{Tii}+x
  • 而由于 T T T 数组倍长过,所以 T i + n = T i T_{i+n}=T_i Ti+n=Ti
  • 故对于所有的 i ∈ [ 1 , n ] i\in[1,n] i[1,n] 都有 T i − i > T i + n − ( i + n ) T_i-i>T_{i+n}-(i+n) Tii>Ti+n(i+n)
  • 所以可以把 max ⁡ \max max 的上界改成 2 n 2n 2n
  • t = max ⁡ i = x 2 n { T i − i } + x t=\max_{i=x}^{2n}\{T_i-i\}+x t=i=xmax2n{Tii}+x
  • a i = T i − i a_i=T_i-i ai=Tii b b b a a a 的后缀最大值数组,那么 t min ⁡ t_{\min} tmin 就是
  • min ⁡ x = 1 n { b x + x } \min_{x=1}^n\{b_x+x\} x=1minn{bx+x}
  • 显然,如果 b b b 在区间 [ l , r ] [l,r] [l,r] 上相等,那么 x x x l l l 比取 l + 1 l+1 l+1 r r r 的任意一个数都优
  • 所以 t min ⁡ t_{\min} tmin 再次化为
  • min ⁡ x = 1 n { b x + x } [ x = 1  OR  b x − 1 > b x ] \min_{x=1}^n\{b_x+x\}[x=1\text{ OR }b_{x-1}>b_x] x=1minn{bx+x}[x=1 OR bx1>bx]
  • 设有数组 c c c ,保存在 [ 1 , n ] [1,n] [1,n] 内满足 b i > b i + 1 b_i>b_{i+1} bi>bi+1 (换句话说, i i i a a a 数组的以 i i i 为开头的前缀最大值)的所有位置 i i i ,设这样的二元组共 m m m
  • 则显然 i i i 1 1 1 m m m a c i a_{c_i} aci 严格单调递减, t min ⁡ t_{\min} tmin 再次转化
  • min ⁡ ( min ⁡ i = 1 m − 1 { a c i + 1 + c i + 1 } , a c 1 + 1 , c m + 1 + max ⁡ i = n + 1 2 n { T i − i } ) \min(\min_{i=1}^{m-1}\{a_{c_{i+1}}+c_i+1\},a_{c_1}+1,c_m+1+\max_{i=n+1}^{2n}\{T_i-i\}) min(i=1minm1{aci+1+ci+1},ac1+1,cm+1+i=n+1max2n{Tii})
  • 于是我们需要维护 c c c 数组的 c 1 , c m c_1,c_m c1,cm 以及 min ⁡ i = 1 m − 1 { a c i + 1 + c i + 1 } \min_{i=1}^{m-1}\{a_{c_{i+1}}+c_i+1\} mini=1m1{aci+1+ci+1}
  • 这是线段树的骚操作——维护前后缀最大值序列 / 单调子序列
  • 具体可右转 线段树维护单调子序列
  • 建议先做 BZOJ 2957 楼房重建
  • 在这里需要让 q u e r y ( u , x ) query(u,x) query(u,x) 返回一个三元组 ( l , r , v a l ) (l,r,val) (l,r,val)
  • 分别表示 c c c 的第一个元素、最后一个元素、对应的 min ⁡ i = 1 m − 1 { a c i + 1 + c i + 1 } \min_{i=1}^{m-1}\{a_{c_{i+1}}+c_i+1\} mini=1m1{aci+1+ci+1}
  • 同时我们发现我们没必要维护倍长后的后半段
  • 因为我们只需要查询 q u e r y ( r o o t , max ⁡ i = n + 1 2 n { T i − i } ) query(root,\max_{i=n+1}^{2n}\{T_i-i\}) query(root,maxi=n+12n{Tii}) 即可
  • r o o t root root 为线段树的根
  • max ⁡ i = n + 1 2 n { T i − i } = − n + max ⁡ i = 1 n { T i − i } \max_{i=n+1}^{2n}\{T_i-i\}=-n+\max_{i=1}^n\{T_i-i\} maxi=n+12n{Tii}=n+maxi=1n{Tii}
  • 复杂度 O ( n log ⁡ 2 n ) O(n\log^2n) O(nlog2n)

Code

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define For(i, a, b) for (i = a; i <= b; i++)
#define p2 p << 1
#define p3 p << 1 | 1

inline int read()
{
	int res = 0; bool bo = 0; char c;
	while (((c = getchar()) < '0' || c > '9') && c != '-');
	if (c == '-') bo = 1; else res = c - 48;
	while ((c = getchar()) >= '0' && c <= '9')
		res = (res << 3) + (res << 1) + (c - 48);
	return bo ? ~res + 1 : res;
}

template <class T>
inline T Max(const T &a, const T &b) {return a > b ? a : b;}

template <class T>
inline T Min(const T &a, const T &b) {return a < b ? a : b;}

const int N = 1e5 + 5, M = N << 2, INF = 0x3f3f3f3f;

int n, m, p, t[N], lst, maxt[M];

struct node
{
	int firs, lsts, firv, res;
} ri[M];

node query(int l, int r, int downs, int p)
{
	if (l == r)
		return maxt[p] >= downs ?
			(node) {l, r, maxt[p], INF} : (node) {0, 0, 0, INF};
	int mid = l + r >> 1;
	if (maxt[p3] < downs) return query(l, mid, downs, p2);
	if (maxt[p2] < maxt[p3]) return query(mid + 1, r, downs, p3);
	node ls = ri[p], rs = query(mid + 1, r, downs, p3);
	if (!ls.firs) return rs;
	return (node) {ls.firs, rs.lsts, ls.firv, Min(Min(ls.res, rs.res),
		rs.firv + ls.lsts + 1)};
}

void build(int l, int r, int p)
{
	if (l == r) return (void) (maxt[p] = t[l] - l);
	int mid = l + r >> 1;
	build(l, mid, p2); build(mid + 1, r, p3);
	maxt[p] = Max(maxt[p2], maxt[p3]);
	ri[p] = query(l, mid, maxt[p3], p2);
}

void change(int l, int r, int pos, int v, int p)
{
	if (l == r) return (void) (maxt[p] = v);
	int mid = l + r >> 1;
	if (pos <= mid) change(l, mid, pos, v, p2);
	else change(mid + 1, r, pos, v, p3);
	maxt[p] = Max(maxt[p2], maxt[p3]);
	ri[p] = query(l, mid, maxt[p3], p2);
}

int main()
{
	int i, x, y;
	n = read(); m = read(); p = read();
	For (i, 1, n) t[i] = read();
	build(1, n, 1);
	node res = query(1, n, maxt[1] - n, 1);
	lst = Min(res.res, t[res.firs] - res.firs + 1);
	if (res.lsts < n) lst = Min(lst, maxt[1] - n + res.lsts + 1);
	printf("%d\n", lst += n - 1);
	while (m--)
	{
		x = read(); y = read();
		if (p) x ^= lst, y ^= lst;
		change(1, n, x, y - x, 1); t[x] = y;
		res = query(1, n, maxt[1] - n, 1);
		lst = Min(res.res, t[res.firs] - res.firs + 1);
		if (res.lsts < n) lst = Min(lst, maxt[1] - n + res.lsts + 1);
		printf("%d\n", lst += n - 1);
	}
	return 0;
}
内容概要:本文围绕直流微电网中带有恒功率负载(CPL)的DC/DC升压转换器的稳定控制问题展开研究,提出了一种复合预设性能控制策略。首先,通过精确反馈线性化技术将非线性不确定的DC转换器系统转化为Brunovsky标准型,然后利用非线性扰动观测器评估负载功率的动态变化和输出电压的调节精度。基于反步设计方法,设计了具有预设性能的复合非线性控制器,确保输出电压跟踪误差始终在预定义误差范围内。文章还对比了多种DC/DC转换器控制技术如脉冲调整技术、反馈线性化、滑模控制(SMC)、主动阻尼法和基于无源性的控制,并分析了它们的优缺点。最后,通过数值仿真验证了所提控制器的有效性和优越性。 适合人群:从事电力电子、自动控制领域研究的学者和工程师,以及对先进控制算法感兴趣的研究生及以上学历人员。 使用场景及目标:①适用于需要精确控制输出电压并处理恒功率负载的应用场景;②旨在实现快速稳定的电压跟踪,同时保证系统的鲁棒性和抗干扰能力;③为DC微电网中的功率转换系统提供兼顾瞬态性能和稳态精度的解决方案。 其他说明:文中不仅提供了详细的理论推导和算法实现,还通过Python代码演示了控制策略的具体实现过程,便于读者理解和实践。此外,文章还讨论了不同控制方法的特点和适用范围,为实际工程项目提供了有价值的参考。
内容概要:该论文介绍了一种名为偏振敏感强度衍射断层扫描(PS-IDT)的新型无参考三维偏振敏感计算成像技术。PS-IDT通过多角度圆偏振光照射样品,利用矢量多层光束传播模型(MSBP)和梯度下降算法迭代重建样品的三维各向异性分布。该技术无需干涉参考光或机械扫描,能够处理多重散射样品,并通过强度测量实现3D成像。文中展示了对马铃薯淀粉颗粒和缓步类动物等样品的成功成像实验,并提供了Python代码实现,包括系统初始化、前向传播、多层传播、重建算法以及数字体模验证等模块。 适用人群:具备一定光学成像和编程基础的研究人员,尤其是从事生物医学成像、材料科学成像领域的科研工作者。 使用场景及目标:①研究复杂散射样品(如生物组织、复合材料)的三维各向异性结构;②开发新型偏振敏感成像系统,提高成像分辨率和对比度;③验证和优化计算成像算法,应用于实际样品的高精度成像。 其他说明:PS-IDT技术相比传统偏振成像方法具有明显优势,如无需干涉装置、无需机械扫描、可处理多重散射等。然而,该技术也面临计算复杂度高、需要多角度数据采集等挑战。文中还提出了改进方向,如采用更高数值孔径(NA)物镜、引入深度学习超分辨率技术等,以进一步提升成像质量和效率。此外,文中提供的Python代码框架为研究人员提供了实用的工具,便于理解和应用该技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值