3230: 相似子串
time limit: 20 sec memory limit: 128 mb
submit: 913 solved: 223
[submit][status]
description
input
輸入第1行,包含3個整數n,q。q代表詢問組數。
第2行是字串s。
接下來q行,每行兩個整數i和j。(1≤i≤j)。
output
輸出共q行,每行乙個數表示每組詢問的答案。如果不存在第i個子串或第j個子串,則輸出-1。
sample input
5 3ababa
3 55 9
8 10
sample output
-1hint
樣例解釋
第1組詢問:兩個子串是「aba」,「ababa」。f = 32 + 32 = 18。
第2組詢問:兩個子串是「ababa」,「baba」。f = 02 + 42 = 16。
第3組詢問:不存在第10個子串。輸出-1。
資料範圍
n≤100000,q≤100000,字串只由小寫字母'a'~'z'組成
source
字尾陣列+二分+rmq
題解:字典序第i?我們給每個排名為i字尾i乙個ed[i]表示截止到排名i,一共有多少個本質不同的子串,然後在ed陣列上lower_bound就可以找到子串的左端點,然後就知道右端點了。
然後求lcp?和lcs?(longest common suffix?)
兩個字尾陣列可以o(nlogn)預處理,o(1)查詢。
hash可以o(n)預處理,o(logn)查詢。
作為蒟蒻我寫了後一種。。。
**:
1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #includeview code10 #include11 #include
12#define inf 1000000000
13#define maxn 150000+5
14#define maxm 500+100
15#define eps 1e-10
16#define ll long long
17#define ull unsigned long long
18#define pa pair19
#define for0(i,n) for(int i=0;i<=(n);i++)
20#define for1(i,n) for(int i=1;i<=(n);i++)
21#define for2(i,x,y) for(int i=(x);i<=(y);i++)
22#define for3(i,x,y) for(int i=(x);i>=(y);i--)
23#define mod 1000000007
24#define base 13131
25using
namespace
std;
26inline ll read()
2730
while(ch>='
0'&&ch<='9')
31return x*f;32}
33int
n,q,s[maxn],t[maxn],t2[maxn],c[maxn],sa[maxn],rk[maxn],h[maxn];
34ll ed[maxn];
35ull hash[maxn],mi[maxn];
36void getsa(int
m)37
57 for1(i,n)rk[sa[i]]=i;
58for(int i=0,k=0,j;ik)
59for(k?k--:0,j=sa[rk[i]-1];s[i+k]==s[j+k];k++);60}
61void
gethash()
6267 inline ull get(int x,int y)
68int
main()
6974 s[n]=0
;75 getsa(26
);76 for1(i,n)ed[i]=n-sa[i]-h[i];
77 for1(i,n)ed[i]+=ed[i-1
];78
gethash();
79while(q--)
8083 ll t=lower_bound(ed+1,ed+n+1,x)-ed,l1=sa[t],r1=sa[t]+h[t]+x-ed[t-1]-1
;84 t=lower_bound(ed+1,ed+n+1,y)-ed;ll l2=sa[t],r2=sa[t]+h[t]+y-ed[t-1]-1;85
int l=0,r=min(r1-l1+1,r2-l2+1
);86
while(l<=r)
8791 ll ans=(ll)r*(ll)r;
92 l=0,r=min(r1-l1+1,r2-l2+1
);93
while(l<=r)
9498 ans+=(ll)r*(ll)r;
99 printf("
%lld\n
",ans);
100}
101return0;
102 }
bzoj 3230 相似子串
time limit 20 sec memory limit 128 mb submit 1767 solved 438 submit status discuss 輸入第1行,包含3個整數n,q。q代表詢問組數。第2行是字串s。接下來q行,每行兩個整數i和j。1 i j 輸出共q行,每行乙個數表示...
BZOJ 3230 相似子串
給定乙個長度為 n 的字串以及 q 組查詢,每組查詢給定 a 和 b 求在所有本質不同子串中排名第 a 和第 b 的串的最長公共字首與最長公共字尾的平方和.n,q le 1 times 10 5 字尾陣列板子題.麻麻我終於會用字尾陣列辣 本來想接著用sam的.但是發現多組查詢排名為 k 的本質不同子...
bzoj3230 相似子串 SA lcp 二分
首先用字尾陣列處理出h陣列。因為要問子串的排名,所以我們再記乙個陣列num i 表示前i個字尾有幾個本質不同的子串。然後我們用二分查詢就可以找到排序後的第i個子串是誰了。然後就是求一下lcp了。還有反過來的lcp。算清角標就好了。還有很坑的一點 可能有超過int範圍個實質不同的字串 include ...