部落格觀賞效果更佳:
github
cnblogs
給定字串 s
ss,設 suf
(i
)suf(i)
suf(i)
表示從 i
ii 開始的字尾。支援 q
qq 個詢問,每次給定 [l,
r]
[l,r]
[l,r
],求這段區間中有多少對 i,j
i,ji,
j 使得 suf
(i
)suf(i)
suf(i)
和 suf(
j)
suf(j)
suf(j)
的最長公共字首長度 ≥
k\ge k
≥k。k
kk 是乙個定值,每次都一樣。
(備註:(i,
j)
(i,j)
(i,j
) 和 (j,
i)
(j,i)
(j,i
) 是同樣的一對,只算一次)
k ≤∣
s∣≤3
×106
,m≤1
05
k\le |s|\le 3\times 10^6,m\le 10^5
k≤∣s∣≤
3×10
6,m≤
105,並且滿足 n2m
≤1015
n^2m\le 10^
n2m≤10
15。n2m
≤1015
n^2m\le 10^
n2m≤10
15?這看起來很奇怪。
冷靜分析一下,這提示著我們,o(n
m)
o(n\sqrt)
o(nm)
的演算法是可以通過的。仔細想一下 ,帶根號的靜態區間詢問的演算法…
莫隊!
然後,suf
(i),
suf(
j)
suf(i),suf(j)
suf(i)
,suf
(j) 最長公共字首長度 ≥
k\ge k
≥k,等價於:i
ii 往後 k
kk 個的子串,和 j
jj 往後 k
kk 個的子串相同。
然後我們要快速比較兩端子串是否相同…
雜湊!
於是問題變為:
處理第 i
ii 位往後 k
kk 個位置的雜湊值,設為 h[i
]h[i]
h[i]
每次詢問,就相當於詢問 h[l
,r
]h[l,r]
h[l,r]
中有多少不重複的數,顯然可以莫隊維護。
#include
#include
using
namespace std;
namespace flandre_scarlet
voidrd(
int cnt,..
.)va_end
(args);}
int n,m,k;
char a[n]
;void
input()
ll pre[n]
,pw[n]
; ll rhash
(int l,
int r)
// range hash,求區間雜湊值
ll h[n]
; unordered_mapint> desc;
struct nodeq[n]
;int sn;
bool
operator
<
(node a,node b)
// 莫隊
// sn 為塊大小
ll cnt[n]
; ll cur=0;
void
add(
int x)
// 加入乙個位置
void
del(
int x)
// 刪除乙個位置
ll ans[n]
;void
soviet()
// 離散化
// 只是乙個重新編號
// 我們只保證:原來相等的還相等,原來不相等的還不相等
// 並不保證 < 的關係 (也沒有必要)
sn=n/
sqrt
(m);
// 塊長開 n/sqrt(m)
// 據說開 sqrt(n) 也不會被卡
f(i,
1,m) q[i]
=(node)
;// 因為右端點 >n-k+1 的時候顯然不可能有長度為 k 的最長公共字首
// 所以 r 和 n-k+1 取 min
sort
(q+1
,q+m+1)
;int l=
1,r=
0; cur=
0ll;
f(i,
1,m)
// 會有這種情況...判掉
while
(r.r)++r,
add(r)
;while
(r>q[i]
.r)del
(r),
--r;
while
(l.l)del
(l),
++l;
while
(l>q[i]
.l)--l,
add(l)
; ans[q[i]
.id]
=cur;}f
(i,1
,m)printf
("%lld\n"
,ans[i]);
}#define flan void
flan ismywife()
#undef int
//long long
}int
main()
洛谷P5112 FZOUTSY(字串雜湊 莫隊)
模板 字尾陣列毒瘤 看見題面上的 字尾 lcp 等字樣,dalao們大概馬上想到字尾陣列了。但是這道題能不能不用字尾陣列呢?其實是我不會字尾陣列 不難想到,lcp ge k 意味著兩個字串的前 k 個字元是相同的,於是大力字串雜湊,用 a x a x a k a x a a x a x a 不難 o...
洛谷 比賽題解
這套題的題目質量很高,寫一發題解。t1 cjwssb最近在物理學科上遇到了難題,他不會計算乙個電路中的總電阻,現在他找到了你,希望你能幫助他。這個電路有如下限定 1 電路只由導線以及電阻為一歐的電阻組成 2 保證電路從左到右連線,即每個電阻或導線的兩個連線點xy保證x 我們可以用dfs求解,這個電路...
洛谷 1196 題解
有30000 30000 3000 0個佇列,初始每個佇列裡有元素1,2 3 30000 1,2,3 cdots 30000 1,2,3 3000 0。兩種指令 1.m mmi iij jj 編號為i ii的佇列整個接到jjj上 2.c cci iij jj 問編號為i ii,j jj的兩個點之間 ...