SNOI2019 字串題解

2022-07-31 09:18:16 字數 1088 閱讀 7577

目錄code:

洛谷p5329

題目意思很明確,但似乎不太好求。還是先看看部分分。

\(\theta(n^2\log n)\),暴力,先得10分。

發現一件事,在比較\(s_i\)和\(s_j\)時,假設\(i,從1到i-1這一段是一樣的,從j+1到n是一樣的,所以我們只要比較原串的i+1~ j和i ~j-1這兩段就行。由於任意相鄰兩個都不相同,所以能\(\theta(1)\)比較。

想到雜湊,雖然雜湊只能判等,但我們只要二分一下,找出兩個字串的最長公共字首,再比較最長公共字首的下乙個位置就行。時間複雜度:\(\theta(n\log^2n)\)

到這應該很明朗了,兩個字尾的最長公共字首,立刻想到字尾陣列。通過\(n\log n\)的預處理,可以\(\theta(1)\)比較,再使用\(\theta(n\log n)\)的快排就可以了。

實測:tle 60分

字尾陣列組似乎常數太大,不能通過。不過想一想我們需要什麼,兩個相鄰字尾的最長公共字首,可以設\(h_i\)為以i和i+1開頭的字尾的最長公共字首的長度,很明顯\(h_i>=h_-1\),其實相當於一起去掉兩個開頭字元,所以\(h_i\)一開始就賦值為\(h_-1\),就可以\(\theta(n)\)預處理h陣列了,最後就可以直接排序了。雖然跑不過眾多大佬的\(\theta(n)\)演算法,但也能通過了。

#includeusing namespace std;

#define cmp(a,b,c) (a+c<=n&&b+c<=n&&y[a]==y[b]&&y[a+c]==y[b+c])

#define min(a,b) (a=10)write(x/10);

putchar(x%10^48);

}void swap(int &a,int &b)

int cmp1(int a,int b)

for(int i=0; i}int main()

for(int i=1; i<=n; i++)ans[i]=i;//初始化

qsort(1,n);

for(int i=1; iwrite(ans[n]),putchar('\n');

return 0;

}

題解 P5329 SNOI2019 字串

用棧的做法來水一發。首先我們有乙個暴力的做法,列舉每個被刪除的字元,然後排序輸出,時間複雜度 o n times n times logn 然後我們觀察一下資料,發現有乙個資料點且任意兩個相鄰字元 a i 與 a 不相等 那麼我們考慮這樣乙個字串 acdedc 比如現在我們比較去掉第三位的字串和去掉...

洛谷 P5329 SNOI2019 字串

暴力是過不了的,雜湊也不行。只能找規律。我們可以發現計刪除原串第i的字元後的新串為pi,則任意pi與pi 1 i include include include include using namespace std const int maxn 1000010 int a maxn int sum...

洛谷P5329 SNOI2019 字串

好像 dfs o n 暴力可以毫無壓力的輕鬆過,當然你要寫 text 也沒人攔你。如果兩個字元相同我們可以發現是一樣的,於是用乙個 a 陣列把這個東西壓起來。如果 s i s 那麼就刪除 s i 如果 s i s 那麼就刪除 s 然後一次 dfs 就解決了。include const int max...