tg 36

tg 36 solution

T1

快速找爹:\(\forall x,fa_x=x-fib_x,\)这个是从定义推出来的

这里\(fib_x\)指的是小于\(x\)的最大的斐波那契数,\(fa_x\)就是(假装建的)树上\(x\)的爹

然后就是\(\forall i,fib_{i+1}\geq 2\cdot fib_{i-1}\),这里\(i\)就是第\(i\)个斐波那契数

证明非常显然:\(fib_{i+1}=fib_i+fib_{i-1}=2\cdot fib_{i-1}+fib_{i-2}\geq 2\cdot fib_{i-1}\)

证明这个就是为了说明树高\(\log n\)

于是暴力找\(fa\)解决单次询问,时间复杂度是对的了

总时间复杂度\(O(m\log n)\)

T2

赛时敲了分块和线段树,\(200\)行而已随便写写

我怀疑我就是那个高级数据结构学傻的

但是线段树比分块慢是我没想到的

正解不是分块但是是个sb二分

就是按照颜色为第一关键字,位置为第二关键字排序

\(1\)操作就是个sb二分查找,主要考虑\(2\)操作

我们考虑\(2\)操作对于整个序列单调性的影响

\(1.\)给定兔子颜色不同

这样\(x\)同颜色的下一个至少\(x+2\)\(x+1\)同颜色的上一个至少是\(x-1\)

于是换了以后位置单调性没有影响

(\(x\)同颜色的上一个和\(x+1\)同颜色的下一个显然是不影响单调性的)

\(2.\)颜色相同

换掉会影响单调性,但是换了和没换有区别吗?

综上所述,直接std::swap(c[x],c[x+1])仍然保证查询正确

于是操作\(2\)就是个sb库函数了

注:给想分块过这个题的同志们一些提示:

维护块内直接开值域数组计数,块数\(225\),值域数组类型short

T3

就是显然能往前调整就往前

依据就是决策包容性

对于\(K=1\)显然的一种方案就是暴力判断区间是否可行

但是这样就\(60\%\)分数,实际上记录下所有不合法情况,考虑当前值是否是不合法情况即可

对于\(K=2\),还是从后往前分组,

判定的时候相当于判定二分图,O3暴力到80

正解其实是并查集,类比1e9年前做过的关押罪犯,使用扩展域的并查集判断,每次判断,处理,合并

一旦碰到冲突的就合并,然后判断是不是已经在一个集合内,

如果已经重了,有两种情况:

如果这个数2倍是完全平方数并且出现恰好2次,前面的数没有和他冲突的,那么没事;否则就要重新分段

这个特判的本质就是在一堆不合法情况里面把合法的排出来

posted @ 2022-09-03 12:02  2K22  阅读(31)  评论(0)    收藏  举报