不定期更新.
Ynoi 維修日志
對數據結構的愛……
聯考出過的 Ynoi 題
聯考題 | Ynoi題 |
---|---|
【六校聯考省選#13】異構體 | Ynoi2018 五彩斑斕的世界 |
【六校聯合省選#13】偏振光 | Ynoi2018 GOSICK |
【0905 聯考】生命樹 | Ynoi2019 美好的每一天~不連續的存在 |
【五校聯考NOIP#11】樹 | Ynoi2018 駄作 |
【五校聯考NOIP#23】以諾 | Ynoi2013 無力回天NOI2017 |
# | 題目 | \(\texttt{Tag}\) | 完成情況 |
---|---|---|---|
Ynoi2011 T1 | 初始化 | 根號分治 | AC |
Ynoi2011 T2 | 遙遠的過去 | Fhq_treap,hash | AC |
Ynoi2012 T1 | 驚惶的SCOI2016 | ||
Ynoi2012 T2 | NOIP2016人生巔峰 | bitset,樹狀數組 | AC |
Ynoi2012 T3 | WC,THUWC,CTSC與APIO2017 | ||
Ynoi2012 T4 | 夢斷SCOI2017 | ||
Ynoi2013 T1 | 無力回天NOI2017 | 線性基,線段樹 | AC |
Ynoi2013 T2 | 文化課 | ||
Ynoi2013 T3 | 對數據結構的愛 | 線段樹,單調隊列 | AC |
Ynoi2013 T4 | 大學 | 樹狀數組,dsu | AC |
Ynoi2013 T5 | D2T2 | ||
Ynoi2013 T6 | Ynoi | Trie,虛樹 | 不會實現(還沒人過?) |
Ynoi2014 T1 | 在太陽西斜的這個世界里 | ||
Ynoi2014 T2 | 置身天上之森 | ||
Ynoi2014 T3 | 等這場戰爭結束之后 | ||
Ynoi2014 T4 | 不歸之人與望眼欲穿的人們 | ||
Ynoi2014 T5 | 人人本着正義之名 | Fhq_treap,位運算 | AC |
Ynoi2014 T6 | 長存不滅的過去,逐漸消失的未來 | ||
Ynoi2015 T1 | 我回來了 | 線段樹 | AC |
Ynoi2015 T2 | 縱使日薄西山 | ||
Ynoi2015 T3 | 即便看不到未來 | ||
Ynoi2015 T4 | 此時此刻的光輝 | 分塊,MR | AC |
Ynoi2015 T5 | 盼君勿忘 | ||
Ynoi2015 T6 | 世上最幸福的女孩 | ||
Ynoi2016 T1 | 炸脖龍I | ||
Ynoi2016 T2 | 掉進兔子洞 | 莫隊,bitset | AC |
Ynoi2016 T3 | 這是我自己的發明 | ||
Ynoi2016 T4 | 鏡中的昆蟲 | AC | |
Ynoi2016 T5 | 誰的夢 | ||
Ynoi2016 T6 | 炸脖龍II | ||
Ynoi2017 T1 | 由乃的OJ | 線段樹,位運算 | AC(遠古代碼) |
Ynoi2017 T2 | 由乃的玉米田 | ||
Ynoi2017 T3 | 由乃打撲克 | 分塊 | 口胡,還沒實現 |
Ynoi2018 T1 | 五彩斑斕的世界 | 第二分塊,dsu | AC |
Ynoi2018 T2 | 末日時在做什么?有沒有空?可以來拯救嗎? | 第六分塊 | 蕪湖,被卡常ing |
Ynoi2018 T3 | 未來日記 | 第一分塊 | |
Ynoi2018 T4 | 天降之物 | 第四分塊 | |
Ynoi2018 T5 | GOSICK | 第十四分塊 | 蕪湖,被卡常ing |
Ynoi2018 T6 | 駄作 | 第七分塊 | |
Ynoi2019模擬賽 T1 | Yuno loves sqrt technology I | 分塊 | AC |
Ynoi2019模擬賽 T2 | Yuno loves sqrt technology II | 莫隊二次離線,值域分塊 | AC |
Ynoi2019模擬賽 T3 | Yuno loves sqrt technology III | 分塊 | AC |
Ynoi2019 T1 | 魔法少女網站 | 第十分塊 | 口胡AC |
Ynoi2019 T2 | Happy Sugar Life | 第十一分塊 | |
Ynoi2019 T3 | 美好的每一天~不連續的存在 | 第十三分塊 | 理解不能.jpg |
Ynoi2019 T4 | Another(暫未公開) | 第三分塊 |
[Ynoi2011] 遙遠的過去
Description
有一種字符集超大的 \(Z\) 語言,這種語言的特點是:
\(1.\) 字符集超大,有 \(2^{31}\) 種字符;
\(2.\) 每個單詞由一系列兩兩不同的字符組成;
\(3.\) 字符既能比較相同和不同,也能比較大小;
\(4.\) 兩個單詞只要離散化后相同,則本質相同。
給定兩個字符串 \(A,B\) ,求 \(B\) 作為子串在 \(A\) 中被匹配的次數。
有 \(q\) 次修改,每次修改 \(B\) 中的一個字符,計算匹配次數。
數據范圍 \(n,m,q\le 10^5\) ,保證字符串時刻合法。
時間限制 \(\texttt{1000 ms}\)
空間限制 \(\texttt{512 MB}\)
Tag
Fhq_treap, hash
Solution
對於 \(A\) 的每連續 \(m\) 個數字,我們可以將其離散化后記為 \(\sum\limits_{i=1}^{m} a_i base^{m-i}\) ,其中
\(base=19260817,mod1=10^9+7,mod2=998244353\) 。
從 \([i,i+m-1]\) 到 \([i+1,i+m]\) ,相當於刪去下標 \(i\) ,加上下標 \(i+m\) ,這可以用 \(Fhq\_Treap\) 快速維護。
同理維護 \(B\) 即可,每次修改即先 \(erase\) 一個數,再 \(insert\) 一個數。
時間復雜度 \(O(nlogn)\)
空間復雜度 \(O(n)\)
[Ynoi2012 T2] NOIP2016人生巔峰
Description
給定一個長為 \(n\) 的序列 \(a\) ,數的值域 \([0,v)\),有 \(2\) 種操作:
\(\texttt{1 l r}\) 詢問區間內是否可以選出兩個非空下標集合 \(X,Y\) ,滿足:
\(1°\) \(X\) 和 \(Y\) 沒有交集;
\(2°\) \(\sum\limits_{i\in X} (a_i+1)=\sum\limits_{i\in Y}(a_i+1)\) 。
如果可以選出,輸出 Yuno
,否則輸出 Yuki
。
\(\texttt{2 l r}\) 修改區間內的數,對於所有 \(l\le i\le r\) ,\(a_i\) 變為 \(a_i^3\ mod\ v\) ,即區間立方。
數據范圍 \(1\le n,m\le 10^5,1\le v\le 1000\)
時間限制 \(\texttt{500 ms}\)
空間限制 \(\texttt{128 MB}\)
Tag
bitset,樹狀數組
Solution
區間內的子集數為 \(2^{r-l+1}\) ,每個區間的 \(sum\) 不超過 \(1000(r-l+1)\) 。
若 \(2^{r-l+1}>1000(r-l+1)\) ,即 \(r-l+1>13\) ,由抽屜原理知必有兩集合 \(sum\) 相等,且不相交。
否則 \(r-l+1\le 13\) ,考慮 \(dp[i][j]=0/1\) 表示前 \(i\) 個數能否拼成 \(j\) 。
如果在某個 \(i\) 滿足 \(dp[i][j]=1\) 且 \(dp[i][j-a[i]-1=1\) 則符合條件。這一過程可以用 \(bitset\) 優化。
區間修改直接用樹狀數組維護一下冪次即可,注意 \(v\le 1000\) ,可以很方便預處理 \(f[i][j]\) 表示 \(i^{3^{2^j}}\ mod\ v\) 的值。
時間復雜度 \(O(m(logn+\frac{16900}{\omega}))\) ,跑不滿
空間復雜度 \(O(n)\) 。
[Ynoi2013 T1] 無力回天NOI2017
Description
給定一個長為 \(n\) 的序列 \(a\) ,實現兩種操作:
-
區間 $[l,r] $ 內的所有數都 \(xor\) 上 \(v\) ;
-
查詢區間 \([l,r]\) 內選任意個數(包括 \(0\) 個)的最大 \(xor\) 和是多少。
數據范圍 \(1\le n,m\le 5\times 10^4, 0\le a_i,v\le 10^9\)
時間限制 \(\texttt{4000 ms}\)
空間限制 \(\texttt{128 MB}\)
Tag
線性基,線段樹
Solution
區間修改線性基並不好維護,因此考慮差分。
定義 \(b_i= a_i\ xor\ a_{i-1}\) ,則 \(a_l,a_{l+1},...,a_r\) 的線性基等於 \(a_l,b_{l+1},b_{l+2},...,b_{r}\) 的線性基(因為 \(a_i\ xor\ a_j\ xor\ a_j=a_i\))。
對於一次修改,相當於在 \(b_l\) 和 \(b_{r+1}\) 上分別插入一個 \(v\) ,查詢即得到 \(a_l\) 的值以及 \(b_{l+1},...,b_r\) 的線性基,插入 \(a_l\) 后求一次 \(.getans(x)\) 即可。
時間復雜度 \(O(qlognlog^2(max\{a_i\}))\) ,跑不滿
空間復雜度 \(O(nlog(max\{a_i\}))\)
[Ynoi2013 T3] 對數據結構的愛
Description
定義函數
函數 \(f(l,r)\) 的偽代碼:
result <- 0
for i <- l to r do
result <- add(result, a[i])
return result
給定一個長為 \(n\) 的序列 \(a\) 以及模數 \(p\),每次查詢區間 \(f(l,r)\) 的值。
數據范圍 \(1\le n\le 10^6, 1\le m\le 2\times 10^5,1\le p\le 10^9,-10^9\le a_i\le 10^9\)
時間限制 \(\texttt{2000 ms}\)
空間限制 \(\texttt{512 MB}\)
Tag
線段樹,單調隊列
Solution
區間 \([l,r]\) 的答案一定可以表示為 \(sum-xp\) ,\(x\) 表示減去 \(p\) 的次數,且顯然有 \(0\le r-l+1\le p\) 。
考慮線段樹,但發現初始值可能會對 \(x\) 產生影響,所以我們對於每個節點都記錄 \(c[i]\) 表示區間 \(x=i\) 的最小初值。
顯然,區間減去 \(x\) 的初始值范圍為 \([c[x],c[x+1]-1]\) 。
分析節點 \(u\) 的合並,記兩兒子為 \(ls\) 和 \(rs\) ,則有 \(c[x+y]=min\left\{ max(c[x],c[y]-(sum[ls]-xp)) \right\}\) 。
考慮什么情況下的 \(x,y\) 是合法的:如果 \(ls\) 最大初始值到都到達不了 \(rs\) 的最小初始值,那么就不合法,即 \((c[ls][x+1]-1)+(sum[ls]-xp)<c[rs][y]\) ,否則合法。
目前合並是 \(O(len^2)\) 的,考慮如何優化。
首先,對於合法的 \((x,y)\) 以及 \((x+1,y-1)\) ,\((x,y)\) 不劣於 \((x+1,y-1)\) ,因此隨着 \(x\) 的遞增,\(y\) 單調不減。
其次,因為要比較不合法的情況,所以還需滿足對於任意 \(x\) ,有 \(c[ls][x+1]-c[ls][x]\ge p\) ,可感性理解,因為要多減一次就需要整體抬 \(p\) 。
這樣,就可以通過單調隊列優化到 \(O(len)\) 。
建樹過程時間復雜度 \(O(nlogn)\) ,空間復雜度 \(O(nlogn)\) ;
查詢的話,直接 \(query\) 了,查到對應區間二分一下,找到對應減去 $p $次數的區間即可,這里時間復雜度 \(O(qlog^2n)\) 。
時間復雜度 \(O(nlogn+qlog^2n)\)
空間復雜度 \(O(nlogn)\)
[Ynoi2013 T6] Ynoi
填個坑吧,放一下 \(sol\)
區間排序和區間異或會將原序列分成一些連續的段,其中一次排序操作會把區間內改為同一個新的連續段,一次異或操作會將區間端點處的段分裂為兩段。顯然在m次操作后,至多產生2m個新的連續段。對同一個連續段,每次排序會覆蓋掉以前排序的效果,而相鄰幾次異或操作的效果可以疊加,所以一個連續段的信息可以用一個已排好序的序列異或上一個數表示。
為了處理連續段的變化,可以用平衡樹維護序列中的連續段,通過打標記來處理操作。對每個連續段內部,用二進制trie維護序列。這里的trie較為特殊,為了節省空間,只維護葉節點構成的虛樹,這樣對一個長度為k的連續段,只需用一棵2k-1個點的trie表示。在trie上維護異或標記和排序標記(表示對這棵子樹先排序后異或),其中異或標記的效果是對整棵子樹內的值異或上一個數,而排序標記的效果是將整棵子樹內由於異或而左子樹大於右子樹的點交換左右子樹。打上排序標記前要先下傳異或標記。在排序時會合並多個連續段,這時將每棵trie打上排序標記,利用trie的合並操作得到合並后的連續段。分裂連續段時可以用trie的分裂操作實現。
[Ynoi2015 T1] 我回來了
Description
有兩種操作:
- 加入一個數 \(h\in [1,n]\)
- 查詢 \([L,R]\) ,計算 \(\sum\limits_{x=L}^{R} f(x)\) ,其中 \(f(x)\) 表示最小的滿足不存在 \(h\in [(f(x)-1)\times x+1,f(x)\times x]\) 的值。
數據范圍 \(1\le n\le 10^5,1\le m\le 10^6\)
時間限制 \(\texttt{1000 ms}\)
空間限制 \(\texttt{256 MB}\)
Tag
線段樹
Solution
可以發現,區間總個數是 \(\frac{n}{1}+\frac{n}{2}+...+\frac{n}{n}=O(nlogn)\) 的,所以重點在於快速處理區間移動。
這里可以通過線段樹打個 \(vector\) 輕松實現,配合一個樹狀數組記錄答案即可。
時間復雜度 \(O(mlogn)\)
空間復雜度 \(O(nlogn)\)
[Ynoi2015 T4] 此時此刻的光輝
Description
給定一個長為 \(n\) 的序列 \(a\) ,\(m\) 次詢問,每次查詢區間 \(d(\prod\limits_{i=l}^{r}a_i)\ mod\ 19260817\),\(d(x)\) 表示 \(x\) 的約數個數。
數據范圍 \(1\le n,m\le 10^5, 1\le a_i\le 10^9\)
時間限制 \(\texttt{2500 ms}\)
空間限制 \(\texttt{512 MB}\)
Tag
分塊,MR
Solution
對於一個 \(x\le 10^9\) ,它至多有兩個 \(>^3\sqrt{x}\) 的質因子,所以預處理 \(\le 1000\) 的質數的指數前綴和。
對於 \(>1000\) 的質數,每個 \(a_i\) 最多有兩個,因此莫隊優化即可。
實測 \(\le 1000\) 的質數有 \(168\) 個,所以可以通過。
時間復雜度 \(O(168n+m(168+\sqrt{n}))\)
空間復雜度 \(O(168n)\)
[Ynoi2016 T2] 掉進兔子洞
太水了,直接塞代碼……
時間復雜度 \(O(\frac{nm}{\omega}+n\sqrt{m})\)
空間復雜度 \(O(\frac{nm}{\omega})\) ,常數 \(\frac{1}{3}\)
[Ynoi2017 T3] 由乃打撲克
Description
給定一個長為 \(n\) 的序列 \(a\) ,\(m\) 次詢問,支持兩種操作:
-
查詢區間 \([l,r]\) 的第 \(k\) 小值
-
區間 \([l,r]\) 加上 \(k\)
數據范圍 \(1\le n,m\le 10^5, -2\times 10^4\le k,a_i \le 2\times 10^4\)
時間限制 \(\texttt{2000 ms}\)
空間限制 \(\texttt{128 MB}\)
Tag
分塊
Solution
設塊長是 \(x\) ,對於修改操作,整塊復雜度 \(O(\frac{n}{x})\) ,零散塊復雜度 \(O(x)\) ;
對於查詢操作,二分答案,整塊復雜度 \(O(\frac{n}{x}log(x))\) ,零散塊復雜度 \(O(x)\) 。
根號平衡一下,取 \(x=\sqrt{nlogn}\) 時可做到 \(O(m\sqrt{nlogn}logn)\) ,然后蕪湖 \(T\) 飛。
考慮將兩個零散塊歸並在一起,形成一個“假塊”。
查詢總復雜度 \(O(\frac{n}{x}log(x)logn)\) ,修改復雜度 \(O(x+\frac{n}{x})\) ,取 \(x=\sqrt{n}logn\) 時可做到 \(O(m\sqrt{n}logn)\) ,可以通過。
時間復雜度 \(O(m\sqrt{n}logn)\)
空間復雜度 \(O(n)\)
Bonus
存在 \(O(m\sqrt{nlogn})\) 的做法。
做法基於復雜的多序列二分。
[Ynoi2018 T1] 五彩斑斕的世界
Description
給定一個長為 \(n\) 的序列 \(a\) ,\(m\) 次詢問,支持兩種操作:
- 將區間 \([l,r]\) 中 \(>x\) 的數減去 \(x\)
- 查詢區間 \([l,r]\) 中 \(x\) 的出現次數
數據范圍 \(1\le n\le 10^6, 1\le m\le 5\times 10^5, 1\le a_i,x\le 10^5+1\)
時間限制 \(\texttt{8000 ms}\)
空間限制 \(\texttt{64 MB}\)
Tag
第二分塊,\(dsu\)
Solution
假設值域和 \(n\) 同階,因為每次是減,所以最大值單調不增。
設當前操作為減 \(x\) ,當前最大值為 \(maxx\) ,則
-
若 \(maxx\ge 2\times x\) ,則可以將 \([1,x]\) 的數整體 \(+x\) ,然后整體減標記 \(+x\)
-
若 \(maxx<2\times x\) ,則暴力將 \([x+1,maxx]\) 的數 \(-x\)
可以發現,定義勢能函數 \(\Phi=max-min\) ,每次操作使得 \(\Delta\Phi=x\) ,暴力操作至多 \(max-min\) 下 就會出現 \(\Phi=0\) ,因此暴力維護復雜度是對的。
關於整體平移,可以用 \(dsu\) 來維護,這里復雜度是 \(O(max\{a_i\}\alpha(max\{a_i\}))\) 的。
本題空間卡的很緊,可以考慮逐塊處理的方式。對於整塊直接平移(對於同一塊來說,由勢能函數知均攤 \(O(n\alpha(n))\)),散塊暴力重構(因為對於一個查詢最多 \(2\) 個散塊,所以均攤 \(2m\) 次暴力重構,這里復雜度 \(O(m\sqrt{n})\) )。
時間復雜度 \(O(n\sqrt{m}\alpha(max\{a_i\}))\)
空間復雜度 \(O(n+m+max\{a_i\})\)
[Ynoi2019模擬賽 T1] Yuno loves sqrt technology I
Description
給定一個長為 \(n\) 的排列 \(a\) ,\(m\) 次詢問, 每次查詢一個區間的逆序對數。
強制在線
數據范圍 \(1\le n,m\le 10^5\)
時間限制 \(\texttt{750 ms}\)
空間限制 \(\texttt{512 MB}\)
Tag
分塊
Solution
簡單處理一下塊與塊間貢獻,塊前后綴與塊貢獻即可。
兩個零散塊間貢獻歸並排序計算即可。
時間復雜度 \(O(n\sqrt{n})\)
空間復雜度 \(O(n\sqrt{n})\)
Bonus
存在低於 \(O(n\sqrt{n})\) 的做法。
[Ynoi2019模擬賽 T2] Yuno loves sqrt technology II
Description
給定一個長為 \(n\) 的序列 \(a\) ,\(m\) 次詢問,每次查詢區間逆序對數。
數據范圍 \(1\le n,m\le 10^5,0\le a_i\le 10^9\)
時間限制 \(\texttt{250 ms}\)
空間限制 \(\texttt{32 MB}\)
Tag
莫隊二次離線,值域分塊
Solution
先將 \(a\) 序列離散化。
記 \(f([l,r],x)\) 表示 \(a[l..r]\) 中 \(>a[x]\) 的個數, \(g([l,r],x)\) 表示 \(a[l..r]\) 中 \(<a[x]\) 的個數。
例如,從 \([l,r]\) 到 \([l,r+1]\) ,\(\Delta = f([l,r],r+1)=f([1,r],r+1)-f([1,l-1],r+1)\) 。
\(f([1,x],x+1),g([1,x],x+1)\) 均可用樹狀數組 \(O(nlogn)\) 預處理。
對於 \(f([1,x],l)..f([1,x],r)\) 考慮 \(O(\sqrt{n})\) 插入,\(O(1)\) 查詢的值域分塊。用 \(sum[x]\) 表示塊與塊間的貢獻,\(qwq[x][i]\) 表示塊內前后綴貢獻。簡單維護即可。
時間復雜度 \(O(n\sqrt{n})\)
空間復雜度 \(O(n)\)
Bonus
存在低於 \(O(n\sqrt{n})\) 的做法。
[Ynoi2019模擬賽 T3] Yuno loves sqrt technology III
Description
給定一個長為 \(n\) 的序列 \(a\) ,\(m\) 次詢問,每次查詢區間眾數出現次數。
強制在線
數據范圍 \(1\le n,m\le 5\times 10^5, 0\le a_i\le 10^9\)
時間限制 \(\texttt{2000 ms}\)
空間限制 \(\texttt{64 MB}\)
Tag
分塊
Solution
顯然 \([l,r]\) 到 \([l,r+1]\) 眾數出現次數至多增加 \(1\) 。
因此預處理 \(F[l][r]\) 表示從塊 \(l\) 到塊 \(r\) 的區間眾數,用 \(vector\) 存每個數出現的下標,然后兩邊零散塊內暴力跑即可。
時間復雜度 \(O(n\sqrt{n})\)
空間復雜度 \(O(n)\)
Bonus
存在 \(O(n^{\sqrt{2}})\) 的做法,依賴快速矩陣乘法而\(\texttt{not practical}\)。