題目:
給出乙個長度為n
n的小寫字母組成的字串,求其中有幾個不同的(斷句)長度為m
m的子串。
50分做法:1≤
m≤n≤
20001≤
m≤n≤
2000
列舉子串開始的位置,再將接下來的m
m位扔進tri
etri
e裡,記錄答案即可。
時間複雜度o(n
2log
)o(n
2log
)**100分做法:1≤
m≤n≤
2000001≤
m≤n≤
2000
00字串has
hhas
h。這道題很詭異的卡單雜湊,所以得用雙雜湊。
我們假設有乙個字串是這樣的:
那麼我們可以取出它前面的ii位。
那麼如果我們呢要取出這個字串的第ll到r
r位,那麼應該怎麼取呢?
我們假設這個字串是乙個十進位制數字。
那麼如果我們要取出這個數字串的第33到6
6位,那麼自然就是:an
s=s[
6]−s
[3−1
]×10
6−(3
−1)a
ns=s
[6]−
s[3−
1]×1
06−(
3−1)
那麼我們可以進一步得到,如果我們要取出這個字串的第ll到r
r位,那麼就是an
s=s[
r]−s
[l−1
]×10
r−(l
−1)a
ns=s
[r]−
s[l−
1]×1
0r−(
l−1)
所以,如果我們把這個字串看成乙個base進製的數字串
,就可以按照上述公式求第ll到r
r位。那麼就有:an
s=s[
r]−s
[l−1
]×ba
ser−
(l−1
)ans
=s[r
]−s[
l−1]
×bas
er−(
l−1)
所以,雜湊就可以這樣用了。
時間複雜度:o(n
log)
o(nl
og)
#include
#include
#include
#include
#define mod1 290182597
#define mod2 163227661
#define base1 3769
#define base2 9439
#define n 200100
#define ll long long
#define mp make_pair
using
namespace std;
int n,m,pow1[n]
,pow2[n]
,hash1[n]
,hash2[n]
,ans;
char c[n]
;mapint,
int>
,int
> p;
ll find1
(int l,
int r)
ll find2
(int l,
int r)
intmain()
ll x,y;
for(
int i=
1;i<=n-m+
1;i++
)printf
("%d\n"
,ans)
;return0;
}
好文章備忘
1 規範了命名空間 地圖 com.mapabc.maps.api.mflexmap 常量 com.mapabc.maps.api.constants 包括 mdisplaystate m s mdirection mmapmousetools malignposition mlanguage mgp...
IT好書好文章
最近讀了一些好書,好文章。在此記錄一下。程式設計之美 這本書裡講了很多看起來很難的,但是經過仔細分析又能寫出來的程式。讀這本書需要比較深的演算法和程式設計功底。裡面的例子個個都很經典。暫時處於 啃起來很難的狀態 不過還是打算畢業之前認真讀兩遍。程式設計珠璣 這本書講了作者親身經歷的一些程式設計問題,...
讀到的好文章
呂氏春秋 中有這麼乙個故事 說是越王有四個兒子,有奸臣說你的大兒子要造反,越王就殺了大兒子 一段時間後奸臣有說你的二兒子要造反,二兒子也被宰了 奸臣就是奸臣,再度上奏說三兒子也要造反,造反當然立斬不赦。但是四兒子現在可不是這麼想的,心想我三個哥哥,奸臣一上奏就被砍頭了,我說不定哪天突然就被宰了,還不...