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次,前面的数没有和他冲突的,那么没事;否则就要重新分段
这个特判的本质就是在一堆不合法情况里面把合法的排出来

浙公网安备 33010602011771号