[2020.6.20]ZJOI2020 Day1游记
又是自闭的一天呢~
考前
早早进考场了。感觉桌子有亿点点小,放鼠标的位置有点窄,不太习惯。
8点50左右公布的密码(验题真的那么难么QwQ)
考时
T1
大致题意:
给出长度为\(n\)的,由\(a\)和\(b\)组成的字符串。\(q\)次询问,每次询问一个区间,求区间中本质不同的,形如\(T=PP\)(由两个相同的串拼成)的子串的数量。
\(40\%\):\(n\le5000\)
另\(20\%\):满足条件的子串(包括相同但是位置不同)不多于\(10^6\)个
另\(20\%\):\(q=1\)
\(100\%\):\(n,q\le2\times10^5\)
\(40\)分就直接哈希,即可\(O(1)\)判断一个字串是否合法,离线询问,倒序枚举询问左端点\(i\),记\(f_j\)表示左端点\(\ge i\),右端点恰好为\(j\)的合法子串数量。对于两个相同但是位置不同的子串,取目前出现的,最晚的那一次。
从\(i+1\)转移到\(i\)只需要加入形如\([i,r]\)的合法字串,同时可以用哈希表维护每一个合法字串最后一次出现的位置。
那么询问\([i,r]\)的答案即为\(\sum_{j=i}^rf_j\),前缀和即可。
时间复杂度\(O(n^2)\)。
本来以为可以写\(80\),仔细一想好像做不了\(q=1\),只有\(60\);结果算上\(40\)暴力总共写了5k,结果还没调完(大悲)
如果能直接找到所有满足条件的字串,用与\(40\)pts相同的方法,用树状数组/线段树维护前缀和就可以做额外的\(20\%\)。
可以考虑后缀树,对于树上每一个节点\(x\),考虑两个树上LCA为\(x\)的后缀\(i,j(i<j)\),如果\(j-i\le len(x)\),那么子串\([i,j+(j-i-1)]\)就是合法的。
所以可以考虑线段树合并,时间复杂度(应该是)\(O(m\log n+n\log^2n)\)。
SAM写挂调了很久,写完还得和40暴力卡到一起。
然后结束前10min写完,直接白给。好在还有40。
T2
大致题意:
给出一个长度为\(n\)的区间的广义线段树(每个节点的中点不一定是正中间),一个操作Modify(l,r)给区间打标记,非叶节点的标记可能会被pushdown掉。
一开始线段树上所有节点没有标记,现在进行\(k\)次操作,每次操作从\(\frac{n(n+1)}{2}\)个区间中等概率随机,求最后有标记节点的数量期望。
\(n\le2\times10^5,k\le 10^9\)
想了30min毫无头绪,写了\(n\le10,k\le4\)和\(k=1\)的点直接跑路。
拿到了20分的好成绩
Upd:当时看到就觉得应该和19年D1T2一样做,但是由于种种原因19年那题没做QwQ,然后就白给了。事后去看了一眼19D1T2并发现思路完全相同。
T3
大致题意:
给出一个非负整数序列\(a_1,a_2,\dots a_n\),每次操作为区间减一,或者区间内奇数/偶数下标减一。求将序列变为全0的最少次数。
多组数据,\(T\le 10\)
\(30\%\):\(n,a_i\le 50\)
\(40\%\):\(n,a_i\le 200\)
\(70\%\):\(n\le 1000,a_i\le 10^9\)
\(100\%\):\(n\le 10^5,a_i\le10^9\)
本来以为能写个\(40/70\)之类的,结果还是写了\(30\)。
可能这就是实力不足的选手吧。
可以考虑每个数有多少是被第一种操作删去的(设为\(d_i\)),那么答案就是\(\sum max(0,d_i-d_{i-1})+max(0,(a_i-d_i)-(a_{i-2}-d_{i-2}))\)。
所以直接一个三维dp,时间复杂度\(O(na^3)\)。
总结
进考场脑子就空白。啥都想不到了
SAM一直学的不是特别好,今天可能是第一次完全自己手写SAM。
于是中间花了一堆时间想SAM的细节,可能有一半左右的部分是自己现场糊的。
于是没写出来(悲)
不过确实很久没写过5k代码了。。。
虽然这次白给了,但是对SAM的理解又加深了一步。
果然学算法还是要自己写自己想。
明天还是尽己所能地写暴力吧/kk
希望明年能进队。