P4243 [JSOI2009]等差数列
2021-05-31 21:03
标签:down 需要 query printf 端点 建议 维护 tip i+1 好题。 我们的两种操作均是等差数列,那就来挖掘一下等差数列的性质。 发现其实就是求该序列的一个 差分序列 ,那么我们就搞出这个序列,这里令 \(s_{i}=a_{i+1}-a_{i}\) 。回头看操作一: 求差分后,它就变成了: 在差分数列 l-1 位置处加上首项 a ; 对区间中每一项都加上公差 d ; 在差分数列 r+1 位置处减去 (r-l+1)*d+a 。 再看操作二(在原数列上): 其等价于(在差分数列上): 然鹅问题并没有变得容易。 几经思索后,我们发现只需要维护四个值即可: 分割区间 \([l,\ r]\) 的最少划分段; 分割区间 \([l,\ r)\) 的最少划分段; 分割区间 \((l,\ r]\) 的最少划分段; 分割区间 \((l,\ r)\) 的最少划分段。 为了方便,顺便维护区间左右端点的值。 那么容易推出以下 pushup 函数: 其它部分不难实现。 如果你是以区间 \([1,\ n-1]\) 去直接建树的,建议特判操作一中 l, r 的越界情况 计算答案时仍需合并,所以多开亿些结点备用。 P4243 [JSOI2009]等差数列 标签:down 需要 query printf 端点 建议 维护 tip i+1 原文地址:https://www.cnblogs.com/sizeof127/p/14614492.html那还用说,当然是相邻两项差相等啦。
void pushup(int k, int lc, int rc){
st(k)=st(lc), ed(k)=ed(rc);int tmp=ed(lc)==st(rc);
l(k)=man(l(lc)+lr(rc)-tmp, ulr(lc)+lr(rc), l(rc)+l(lc));
r(k)=man(lr(lc)+r(rc)-tmp, lr(lc)+ulr(rc), r(rc)+r(lc));
lr(k)=man(lr(lc)+lr(rc)-tmp, r(lc)+lr(rc), l(rc)+lr(lc));
ulr(k)=man(l(lc)+r(rc)-tmp, ulr(lc)+r(rc), ulr(rc)+l(lc));
}
Tip:
Code
#include
大常数选手喜提最优解。
上一篇:HTTP头的Expires与Cache-control
下一篇:HTML(六)表格