輸入第1行,包含3個整數n,q。q代表詢問組數。
第2行是字串s。
接下來q行,每行兩個整數i和j。(1≤i≤j)。
輸出共q行,每行乙個數表示每組詢問的答案。如果不存在第i個子串或第j個子串,則輸出-1。
5 3ababa
3 55 9
8 10
1816
-1樣例解釋
第1組詢問:兩個子串是「aba」,「ababa」。f = 32 + 32 = 18。
第2組詢問:兩個子串是「ababa」,「baba」。f = 02 + 42 = 16。
第3組詢問:不存在第10個子串。輸出-1。
資料範圍
n≤100000,q≤100000,字串只由小寫字母'a'~'z'組成
建立字尾陣列,h和pr陣列。。。
查詢字典序為i的串,我們知道以i開頭的不同的字串是n-h[i]-sa[i]那麼就可以二分的尋找i,
然後用線段樹或者st演算法預處理h,pr陣列,然後每次查詢即可。。。
**來自黃學長。。
1 #include2 #includeview code3 #include4 #include5 #include6 #include7 #include8 #include9
#define inf 1000000000
10#define ll long long
11using
namespace
std;
12ll read()
1316
while(ch>='
0'&&ch<='9')
17return x*f;18}
19int n,m,log[100005
];20
char ch[100005
];21
struct
sa28
void mul(int *sa,int *rk,int *sa,int *rk)
36void
getsa()50}
51void
pre()
63int query(int a,int
b)69
void
print()
72}a,b;
73int
main()
7483 id=lower_bound(a.s+1,a.s+n+1,l)-a.s;
84 a1=a.sa[a.p][id];
85 b1=a.sa[a.p][id]+a.h[id]-1+l-a.s[id-1
];86 id=lower_bound(a.s+1,a.s+n+1,r)-a.s;
87 a2=a.sa[a.p][id];
88 b2=a.sa[a.p][id]+a.h[id]-1+r-a.s[id-1
];89 ll t=(a1==a2)?inf:a.query(a1,a2);
90 t=min(t,min(b1-a1+1,b2-a2+1));ans+=t*t;
91 t=(n-b1+1==n-b2+1)?inf:b.query(n-b1+1,n-b2+1
);92 t=min(t,min(b1-a1+1,b2-a2+1));ans+=t*t;
93 printf("
%lld\n
",ans);94}
95return0;
96 }
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 相似子串
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。...