[BZOJ 3160] 万径人踪灭
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ 3160] 万径人踪灭相关的知识,希望对你有一定的参考价值。
题意
给定一个长度为 n , 由 ‘a‘, ‘b‘ 组成的字符串 S .
问有多少个子序列, 满足:
① 坐标对称.
② 字符对称.
③ 不连续.
n <= 100000 .
分析
坐标对称, 则要满足对应坐标的值相同.
满足①② 的所有用 FFT 求.
满足①②!③ 的所有用 Manacher 求.
实现
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cctype> 5 #include <cmath> 6 #include <algorithm> 7 using namespace std; 8 #define F(i, a, b) for (register int i = (a); i <= (b); i++) 9 #define db double 10 11 const int N = 300000; 12 const int MOD = (int)1e9+7; 13 const db PI = acos(-1); 14 15 char s[N]; int n, sum; 16 17 char t[N]; int nT, E[N]; 18 void Manacher(void) { 19 nT = n<<1|1, t[0] = ‘<‘, t[1] = ‘+‘, t[nT+1] = ‘>‘; 20 F(i, 1, n) t[i<<1] = s[i], t[i<<1|1] = ‘+‘; 21 22 for (int i = 1, id = 0; i <= nT; i++) { 23 int j = (id+E[id]-1 <= i ? 1 : min(E[id+id-i], id+E[id]-i)); 24 while (t[i+j] == t[i-j]) j++; 25 E[i] = j; 26 if (id+E[id] < i+E[i]) id = i; 27 } 28 29 F(i, 1, nT) 30 sum = (sum - (E[i] >> 1)) % MOD; 31 } 32 33 int Pow[N], cnt[N]; 34 struct Comp { 35 db x, y; 36 friend inline Comp operator + (Comp A, Comp B) { return (Comp){A.x + B.x, A.y + B.y}; } 37 friend inline Comp operator - (Comp A, Comp B) { return (Comp){A.x - B.x, A.y - B.y}; } 38 friend inline Comp operator * (Comp A, Comp B) { return (Comp){A.x * B.x - A.y * B.y, A.x * B.y + A.y * B.x}; } 39 }A[N], B[N], rot[N][2]; 40 int Bit, Len, Rev[N]; 41 42 void FFT(Comp *A, int sign) { 43 F(i, 0, Len - 1) 44 if (i < Rev[i]) 45 swap(A[i], A[Rev[i]]); 46 for (int i = 2; i <= Len; i <<= 1) { 47 Comp wn = rot[i][sign]; 48 for (int j = 0; j < Len; j += i) { 49 Comp w = (Comp){1, 0}; 50 F(k, 0, i/2-1) { 51 Comp x = A[j+k], y = w * A[j+k+i/2]; 52 A[j+k] = x+y, A[j+k+i/2] = x-y; 53 w = w * wn; 54 } 55 } 56 } 57 if (sign == 1) 58 F(i, 0, Len-1) 59 A[i] = (Comp){A[i].x / Len, 0}; 60 } 61 void Work(void) { 62 Pow[0] = 1; 63 F(i, 1, n) Pow[i] = (Pow[i-1] << 1) % MOD; 64 65 for (Bit = 0, Len = 1; Len <= n+n; Bit++, Len <<= 1); 66 F(i, 1, Bit) { 67 int k = 1 << i; 68 rot[k][0] = (Comp){cos(2 * PI / +k), sin(2 * PI / +k)}; 69 rot[k][1] = (Comp){cos(2 * PI / -k), sin(2 * PI / -k)}; 70 } 71 F(i, 1, Len-1) Rev[i] = Rev[i >> 1] >> 1 | (i & 1) << (Bit - 1); 72 73 F(i, 1, n) 74 A[i] = (Comp){s[i] == ‘a‘, 0}, B[i] = (Comp){s[i] == ‘b‘, 0}; 75 76 FFT(A, 0); 77 FFT(B, 0); 78 F(i, 0, Len-1) 79 A[i] = A[i] * A[i] + B[i] * B[i]; 80 FFT(A, 1); 81 82 F(i, 1, n) cnt[i << 1]++; 83 F(i, 2, n + n) { 84 cnt[i] += (int)(A[i].x + 0.5); 85 cnt[i] >>= 1; 86 sum = (sum + Pow[cnt[i]] - 1) % MOD; 87 } 88 } 89 90 int main(void) { 91 #ifndef ONLINE_JUDGE 92 freopen("bzoj3160.in", "r", stdin); 93 #endif 94 95 scanf("%s", s+1); 96 n = strlen(s+1); 97 98 Manacher(); 99 Work(); 100 printf("%d\n", (sum + MOD) % MOD); 101 102 return 0; 103 }
以上是关于[BZOJ 3160] 万径人踪灭的主要内容,如果未能解决你的问题,请参考以下文章