前言
在繁忙的文化课生活后,我得以have a rest,来到北京参加APIO,然而,这APIO似乎并没有使我感到轻松
比赛历程
其它不说了,讲课听起来挺奇怪的,就直接从比赛写起吧
好久不写博客了,总结一下十分必要,确实应从每一次的比赛中吸取教训
这次比赛,开场写读优,大概好久不写OI题了,所一读输优写挂调了20min
然后感觉linux的编辑器太丑、不好用,又调了10分钟
准备工作做完后,感觉神清气爽,但是意识到时间已经过去了很久
看完3题,决定从T1开始写
第一档暴力直接写完,写第二档暴力的时候卡了好一会儿,因为
n
=
1
n=1
n=1的时候会RE
然后就去开3,一开始想树套树
→
\rightarrow
→二维线段树
→
\rightarrow
→cdq分治
虽然万年不写,但感觉思路还是在的,于是准备刚一波
200line的代码,调了两个错误,就过T3了
此时的我松了一口气,丝毫没有发现2是一道水题,想都不想就从最低的暴力开始写,以至于推到后面的时候问题已经被我转化的非常复杂,最终只获得了20分,T1多写了一个没有一操作部分分,然后就结束了
最终43+20+100=163,然而其实T2很简单,而3的暴力分有60,所以大众分是43+100+60,被打爆了
事后思考了一下,T1正解无非是最后写的没有二操作的写法套一个分块,T2直接推一个代数的式子就好了(具体的这里暂不贴)
正常比赛的题想到了代码都不是很难,而且思路都想到了
最遗憾的不是不会做,而是与正解擦肩而过
这比赛没发挥好还是有很多因素的:
1.代码能力不佳,对是否写出3不自信,导致写完后就有太大仔细,没再想正解
2.对于linux操作系统的使用不够熟练
3.对题目的发散应用的实际解题的能力不足
感觉过去一年做了很多题,但是在方法上并没有怎么提升,这其实是很有问题的
题解
鉴于主办方要求比赛后2日内不要在网上上传题解,所以此处将在之后进行补充
——2019/5/19
update: 2019/5/20
过了2天了,那应该也可以放题解了
T1
题目大意: 给出一幅图,有两种操作:
一种是改一条边的边权
另一种是询问,从一个点开始,每次经过权值大于等于自己权值的边,求可达点的集合大小
正解:
先考虑没有修改操作,我们发现直接将边和询问的权值分别排序,扫一下当前权值,即维护“经过权值大于等于
x
x
x的边”的联通块,用并查集维护即可
复杂度
O
(
n
l
o
g
n
)
\mathcal O(nlogn)
O(nlogn)
我们考虑如果有修改操作怎么办
考虑分块(真的只要想到分块就好了)
我们把所有操作分块(设块大小是
P
P
P),对于每个块内的操作单独处理
我们发现对于快外的询问很方便处理,那么我们先把块内操作修改的边删去,扫一遍,我们发现这个扫一遍的复杂度是
O
(
n
α
)
\mathcal O(n\alpha)
O(nα)的,那么所有块的复杂度就是
O
(
n
P
α
)
\mathcal O(nP\alpha)
O(nPα),我们考虑块内有修改的边,我们只要在询问时暴力把那些有修改的边加入即可,我们发现有修改的边最多只有
O
(
n
P
)
\mathcal O(\frac{n}{P})
O(Pn)条,由于需要使用并查集,所以总复杂度
O
(
n
2
P
l
o
g
n
)
\mathcal O(\frac{n^2}{P}logn)
O(Pn2logn)
这样我们发现
P
=
n
l
o
g
n
α
P=\sqrt {nlogn\alpha}
P=nlognα时总复杂度最低,为
O
(
n
n
l
o
g
n
α
)
\mathcal O(n\sqrt{nlogn\alpha})
O(nnlognα)
PS:听说本题可以使用路径压缩使得复杂度降为
O
(
n
n
α
)
\mathcal O(n\sqrt{n\alpha})
O(nnα),但我想了一下好像
α
\alpha
α是均摊的,所以好像不太行,如果有什么高论可以来与我讨论
update by 2019/7/2: 经过yyb的提醒,我发现自己扫一遍的复杂度中的
α
\alpha
α忘记加了,现已更新
T2
题目大意: 对于一个
t
t
t对应一个数对
(
t
+
⌊
t
B
⌋
m
o
d
  
A
,
t
m
o
d
  
B
)
(t+\left\lfloor\frac tB\right\rfloor\mod A,t\mod B)
(t+⌊Bt⌋modA,tmodB),给出
n
n
n组
t
t
t的范围,问对应的数对有多少种
正解:
本题部分分极少,而且比正解着实难写许多,所以这里就不讲了
本题其实是要推一个结论,即如果
t
1
,
t
2
t_1,t_2
t1,t2对应的数相同,那么当且仅当
t
1
≡
t
2
(
m
o
d
A
∗
B
g
c
d
(
A
,
B
+
1
)
)
t_1\equiv t_2\pmod{\frac{A*B}{gcd(A,B+1)}}
t1≡t2(modgcd(A,B+1)A∗B)
直接线段求交即可
具体分析是,我们发现它是循环
我们考虑与
t
=
0
t=0
t=0循环的第一个位置
t
1
t_1
t1
t
1
m
o
d
  
B
≡
0
t_1\mod B\equiv0
t1modB≡0
那么即
t
1
(
B
+
1
)
B
m
o
d
  
A
≡
0
\frac{t_1(B+1)}{B}\mod A\equiv 0
Bt1(B+1)modA≡0
又要
t
1
t_1
t1最小,那么就
t
1
=
A
∗
B
g
c
d
(
A
,
B
+
1
)
t_1=\frac{A*B}{gcd(A,B+1)}
t1=gcd(A,B+1)A∗B
T3
题目大意:
有一个n+1个点、n条边的链,有两种操作:
改变一条边的状态(黑变白或者白变黑)
询问两个灯a,b之间的边,从开始到现在有多少个时刻边全是白色的
题解:
首先用一个set维护当前的每一段边是白色的连续段,用数据结构维护点对满足条件的时刻数,当有修改操作时直接更新数据结构和set即可
容易想的有树套树、二维线段树
我写的cdq分治+树状数组
本题想到了做法的话剩下的就是靠码力了
复杂度
O
(
n
l
o
g
2
n
)
\mathcal O(nlog^2n)
O(nlog2n)
总结
十年OI一场空(大雾)
以前觉得OI就是一个竞赛,现在发现,OI其实反映出我自身的许多问题
前路漫漫,进无止尽!