标签:select ant mes stc main ase ide gic chm
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 576 Accepted Submission(s): 287
Problem Description
Harry got a string T, he wanted to know the number of T’s disjoint palindrome substring pairs. A string is considered to be palindrome if and only if it reads the same backward or forward. For two substrings of T:x=T[a1…b1],y=T[a2…b2](where a1 is the beginning index of x,b1 is the ending index of x. a2,b2 as the same of y), if both x and y are palindromes and b1<a2 or b2<a1 then we consider (x, y) to be a disjoint palindrome substring pair of T.
Input
There are several cases.
For each test case, there is a string T in the first line, which is composed by lowercase characters. The length of T is in the range of [1,100000].
Output
For each test case, output one number in a line, indecates the answer.
Sample Input
aca aaaa
Sample Output
3 15
Hint
For the first test case there are 4 palindrome substrings of T. They are: S1=T[0,0] S2=T[0,2] S3=T[1,1] S4=T[2,2] And there are 3 disjoint palindrome substring pairs. They are: (S1,S3) (S1,S4) (S3,S4). So the answer is 3.
Source
Recommend
heyang | We have carefully selected several similar problems for you: 6447 6446 6445 6444 6443
题意:
在一个S串中找两个回文串,两个回文串没有重叠的部分。问有多少个这样的回文串对。
思路:
用manacher我们可以求出以$i$为中心的回文串的个数。
$pre[i]$表示以$i$为开头的回文串的个数,$suf[i]$表示以$i$为结尾的回文串的个数。
那么我们要求的答案其实就是$\sum_{i = 1}^{len} pre[i] * (\sum_{j=1}^{i-1} suf[j])$
所以我们再用一个数组$sum$来存$suf$数组的前缀和。
那么$pre$和$suf$怎么求呢?
我们manacher处理出的$p[i] /2$表示的是以$i$为中心的回文的个数。
那么对于$i$之前的半径内的字符,他们的$pre$可以$+1$。同样他之后的半径内的字符,$suf$可以$-1$
暴力统计肯定是不行的,我们可以使用差分的思想。
对于$[i,j]$区间内的每一个数都更新$k$的话,我们可以用一个数组$add[i] += k$,add[j+1] -=k$
然后从前往后求前缀和得到的就是对区间的全部更新了。求$suf$和$pre$也是同样的道理。
$pre$是后面影响前面的所以从后往前求“#”向前靠,$suf$从前往后求“#”向后靠。
1 #include<iostream> 2 //#include<bits/stdc++.h> 3 #include<cstdio> 4 #include<cmath> 5 //#include<cstdlib> 6 #include<cstring> 7 #include<algorithm> 8 //#include<queue> 9 #include<vector> 10 //#include<set> 11 //#include<climits> 12 //#include<map> 13 using namespace std; 14 typedef long long LL; 15 #define N 100010 16 #define pi 3.1415926535 17 #define inf 0x3f3f3f3f 18 19 const int maxn = 1e5 + 5; 20 char s[maxn], ss[maxn * 2]; 21 LL pre[maxn * 2], suf[maxn * 2], sum[maxn * 2]; 22 int lens, p[maxn * 2]; 23 24 int init() 25 { 26 ss[0] = ‘$‘; 27 ss[1] = ‘#‘; 28 int lenss = 2; 29 for(int i = 0; i < lens; i++){ 30 ss[lenss++] = s[i]; 31 ss[lenss++] = ‘#‘; 32 } 33 ss[lenss] = ‘\0‘; 34 return lenss; 35 } 36 37 void manacher() 38 { 39 int lenss = init(); 40 int id, mx = 0; 41 for(int i = 1; i < lenss; i++){ 42 if(i < mx){ 43 p[i] = min(p[2 * id - i], mx - i); 44 } 45 else{ 46 p[i] = 1; 47 } 48 while(ss[i - p[i]] == ss[i + p[i]])p[i]++; 49 if(mx < i + p[i]){ 50 id = i; 51 mx = i + p[i]; 52 } 53 54 } 55 } 56 57 int main() 58 { 59 while(scanf("%s", s) != EOF){ 60 lens = strlen(s); 61 /*for(int i = 0; i < lens * 2 + 3; i++){ 62 p[i] = 0; 63 }*/ 64 for(int i = 0; i < lens + 1; i++){ 65 suf[i] = pre[i] = sum[i] = 0; 66 } 67 68 manacher(); 69 70 for(int i = 2; i <= lens * 2; i++){ 71 int x = (i + 1) / 2;//向上取整 72 suf[x]++, suf[x + (p[i] / 2)]--; 73 } 74 for(int i = lens * 2; i >= 2; i--){ 75 int x = i / 2; 76 pre[x]++, pre[x - (p[i] / 2)]--; 77 } 78 79 for(int i = lens; i >= 1; i--){ 80 pre[i] += pre[i + 1]; 81 } 82 for(int i = 1; i <= lens; i++){ 83 suf[i] += suf[i - 1]; 84 sum[i] += sum[i - 1] + suf[i]; 85 } 86 LL ans = 0; 87 for(int i = 1; i <= lens; i++){ 88 ans += (LL)pre[i] * sum[i - 1]; 89 } 90 printf("%I64d\n", ans); 91 } 92 return 0; 93 }
hdu5157 Harry and magic string【manacher】
标签:select ant mes stc main ase ide gic chm
原文地址:https://www.cnblogs.com/wyboooo/p/9988397.html