題目描述先考慮 \(l=1,r=|s|\) 的情況 \((68pts)\)小 \(a\) 被選為了 \(ion2018\) 的出題人,他精心準備了一道質量十分高的題目,且已經把除了題目命名以外的工作都做好了。
由於 \(ion\) 已經舉辦了很多屆,所以在題目命名上也是有規定的,\(ion\) 命題手冊規定:每年由命題委員會規定乙個小寫字母字串,我們稱之為那一年的命名串,要求每道
題的名字必須是那一年的命名串的乙個非空連續子串,且不能和前一年的任何一道題目的名字相同。
由於一些特殊的原因,小 \(a\) 不知道 \(ion2017\) 每道題的名字,但是他通過一些特殊手段得到了 \(ion2017\) 的命名串,現在小 \(a\) 有
\(q\) 次詢問:每次給定 \(ion2017\) 的命名串和 \(ion2018\) 的命名串,求有幾種題目的命名,使得這個名字一定滿足命題委員會的規定,即是 \(ion2018\) 的命名串的乙個非
空連續子串且一定不會和 \(ion2017\) 的任何一道題目的名字相同。
由於一些特殊原因,所有詢問給出的 \(ion2017\) 的命名串都是某個串的連續子串,詳細可見輸入格式。
我們可以對 \(s\) 建出 \(sam\),把 \(t\) 扔到上面跑匹配得到陣列 \(l\)
如果不考慮本質不同這一限制,那麼答案就是 \(\sum\limits_^i-l[i]\)
然後考慮怎麼去重,我們同時對 \(t\) 建出 \(sam\),同時對每個點處理出 \(pos[i]\),即該狀態第一次出現位置
那麼每個點對答案的貢獻就是 \(\sum\limits_^len[i]-max(len[f[i]],l[pos[i]])\)
然後考慮任意區間的情況 \((100pts)\)
發現我們需要快速得到乙個區間的 \(sam\),然而並沒有什麼好的方法
再仔細想想,我們真的一定要得到這段區間的 \(sam\) 嗎?
其實我們只需要借助 \(sam\) 求出 \(l\) 陣列
而觀察 \(l=1,r=|s|\) 的情況,對於 \([l,r]\) 我們需要以下幾種操作
發現其實在 \([1,|s|]\) 的 \(sam\) 上也可以實現這些操作,主要問題在於怎麼查詢點 \(x\) 在 [l,r] 內是否有 \(c\) 這個轉移
發現這本質上是求點 \(ch[x][c]\) 的 \(endpos\) 集合中是否有 \([l+length,r]\) 之間的點
處理一下 \(endpos\) 集合就可以查詢了
還有就是我們跳 \(parent\) 前應該先減小 \(length\) 查詢是否匹配
總複雜度 \(o(|s|log|s|+\sum\limits_^q |t_i|log|t_i|)\)
NOI2018 你的名字
sam寫的太不熟練了 sam上的線段樹合併也不熟練 調了半天樣例 給定乙個s,q次詢問,每次給出t,l,r,求對於s l,r 屬於t的子串卻不屬於s l,r 的子串有多少個 看上去挺簡潔的乙個問題。對於s 1,n 68pts?如果做過 heoi2015 最短不公共子串 就好做多了!可以對a,b分別建...
NOI2018 你的名字
嘟嘟嘟 這題以前寫過棄掉了,後來竟然連自己的68分寫法都看不懂了 這次回首這道題,心想怎麼說也得把這題切了,哪怕抄題解也行。但沒想到別人的題解自己怎麼也看不懂,最終還是自己搞出來了 我真nb 總用時前一天下午到第二天凌晨0 30 第二天半個上午。我們先來回顧 l 1,r n 的情況。大體思路就是求出...
NOI2018 你的名字
實力強大的小 a 被選為了 ion2018 的出題人,現在他需要解決題目的命名問題。小 a 被選為了 ion2018 的出題人,他精心準備了一道質量十分高的題目,且已經把除了題目命名以外的工作都做好了。由於 ion 已經舉辦了很多屆,所以在題目命名上也是有規定的,ion 命題手冊規定 每年由命題委員...