推薦一篇我覺得很好理解的部落格
首先考慮暴力:令 \(t=ab\),從小到大列舉 \(t\) 的長度,找到最短的 \(c_1\) ,列舉有多少個 \(t\) 的真字首 \(a\) 滿足 \(f(a) \leqslant f(c_1)\),
之後令 \(c_2=abc\),再令$ c_3=ababc$……以此類推
考慮優化。結合上面的暴力分析,容易想到 \(f(c_k)\) 的前面的所有 \(abab\)均不會對其產生貢獻,故有 \(f(c_)=f(c_1)\), \(f(c_)=f(c_2)\)
所以,$ a\(,\)b\(,\)c$ 是一組解就意味著 \(a\),\(b\),\(ababc\)也是一組解(如果 \(ab\) 的重複次數 \(\geqslant 3\)),
那麼我們無需列舉所有的 \(c_k\),而只需計算 \(c_1\) 與 \(c_2\) 解的數量,再分別乘上有多少$ c_k$ 與其相同即可
最後我們發現時間複雜度的瓶頸在於找到最短的 \(c\),看出這個問題本質是求 \(t\) 的最大重複次數,使用字串 \(hash\) 即可
此演算法是 \(n (\ln n+\log_2 26)\)的
——以上均摘自開頭說的部落格em
求\(c_1\)
\(c_2\)的解的數量, 我們只需要找到\(t\)的真字首中有多少個滿足條件的即可 應該...能想到用樹狀陣列來維護叭
對於字串\(s\)的每個字尾的 出現奇數次的字母的數量 我們也可以提前處理出來 這樣就能很快確定c的
出現奇數次的字母的數量啦
#include using namespace std;
#define ll long long
const int n = 1 << 20 + 5;
ll n, ans, jcnt;//jcnt代表當前有多少個奇數次的字元數
char s[n];
ll bit[30];//bit[i]代表有字串s有多少個的字首有不超過i個奇數次的字元的數量
ll discnt[n];//discnt[i]表示s[i - n]有的多少個奇數次的字元的數量
bool isj[30], disj[30];//isj[1 - 26]分別表示a - z的數量是否為奇數次, disj意義相同,只不過是倒序的
unsigned long long h[n], p;//h: 雜湊值
int lowbit(int x)
void add(int x)
}ll ask(int x)
return sum;
}int main()
for(int i = 1; i <= len; i++)
h[i] = h[i - 1] * 233 + s[i];
add(1);
jcnt = 1;
isj[s[1] - 'a'] = 1;
for(int i = 2; i < len; i++)
if(x * i == len) ans += bit[1] * ((x - 1) / 2);//當x * i == len時c不能是空串所以最短的c應該是abab, 會比其他的情況少一種
else ans += ask(discnt[x * i + 1]) * ((x - 1) / 2 + 1);//c1, c3, c5...的解的數量
ans += ask(discnt[(x - 1) * i + 1]) * (x / 2);//c2, c4, c6...的解的數量
isj[s[i] - 'a'] = !isj[s[i] - 'a'];
add(isj[s[i] - 'a'] ? ++jcnt : --jcnt);//最後再更新, 否則可能會導致b為空串
p *= 233;//t的長度增加, p也應該增加
} printf("%lld\n", ans);
} return 0;
}
201409 3 字串匹配
試題編號 201409 3 試題名稱 字串匹配 時間限制 1.0s 記憶體限制 256.0mb 問題描述 問題描述 給出乙個字串和多行文字,在這些文字中找到字串出現的那些行。你的程式還需支援大小寫敏感選項 當選項開啟時,表示同乙個字母的大寫和小寫看作不同的字元 當選項關閉時,表示同乙個字母的大寫和小...
20140903 字串匹配
問題描述 試題編號 201409 3 試題名稱 字串匹配 時間限制 1.0s 記憶體限制 256.0mb 問題描述 問題描述 給出乙個字串和多行文字,在這些文字中找到字串出現的那些行。你的程式還需支援大小寫敏感選項 當選項開啟時,表示同乙個字母的大寫和小寫看作不同的字元 當選項關閉時,表示同乙個字母...
201409 3 字串匹配
問題描述 給出乙個字串和多行文字,在這些文字中找到字串出現的那些行。你的程式還需支援大小寫敏感選項 當選項開啟時,表示同乙個字母的大寫和小寫看作不同的字元 當選項關閉時,表示同乙個字母的大寫和小寫看作相同的字元。輸入格式 輸入的第一行包含乙個字串s,由大小寫英文本母組成。第二行包含乙個數字,表示大小...