1. 程式人生 > >[BZOJ 3160] 萬徑人蹤滅

[BZOJ 3160] 萬徑人蹤滅

stdin 給定 ++ type bzoj sin blog ctype 對稱

題意

  給定一個長度為 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] 萬徑人蹤滅