zoukankan      html  css  js  c++  java
  • bzoj4503 两个串

    题意:给定两个串s,t。其中t可能含有?,可以代表任一字符。

    求t在s中一共出现了多少次。

    解:

    我有个想法是在后缀自动机上DFS,然后发现不记忆化会超时,记忆化又不对。

    正解是FFT。我们发现如果把问号看做0,那么两个字符匹配就是(a - b)b = 0

    然后整串匹配就是∑(a - b)²b = 0

    我们发现这个是顺着来的,不好搞,那么把第二个串reverse,就变成卷积了。

    ∑a²b - 2ab² + b3 = 0,前两项可以看做是两个卷积,直接卷起来。这时卷积多项式的系数就是串t在s中的某个位置进行匹配的结果。

    第三项对于t在s中的任一位置来说都是相同的,直接加。

    然后把答案 + 0.5转int就行了,某个位置为0就是答案。

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <cstring>
      4 #include <cmath>
      5 
      6 typedef long long LL;
      7 const int N = 100010;
      8 const double pi = 3.1415926535897932384626, eps = 1e-9;
      9 
     10 struct cp {
     11     double x, y;
     12     cp(double X = 0.0, double Y = 0.0) {
     13         x = X;
     14         y = Y;
     15     }
     16     inline cp operator +(const cp &w) const {
     17         return cp(x + w.x, y + w.y);
     18     }
     19     inline cp operator -(const cp &w) const {
     20         return cp(x - w.x, y - w.y);
     21     }
     22     inline cp operator *(const cp &w) const {
     23         return cp(x * w.x - y * w.y, x * w.y + y * w.x);
     24     }
     25 }a[N << 2], b[N << 2];
     26 
     27 int r[N << 2];
     28 char s[N], str[N];
     29 double ans[N << 2];
     30 
     31 inline void FFT(int n, cp *a, int f) {
     32     for(int i = 0; i < n; i++) {
     33         if(i < r[i]) {
     34             std::swap(a[i], a[r[i]]);
     35         }
     36     }
     37 
     38     for(int len = 1; len < n; len <<= 1) {
     39         cp Wn(cos(pi / len), f * sin(pi / len));
     40         for(int i = 0; i < n; i += (len << 1)) {
     41             cp w(1, 0);
     42             for(int j = 0; j < len; j++) {
     43                 cp t = a[i + len + j] * w;
     44                 a[i + len + j] = a[i + j] - t;
     45                 a[i + j] = a[i + j] + t;
     46                 w = w * Wn;
     47             }
     48         }
     49     }
     50 
     51     if(f == -1) {
     52         for(int i = 0; i <= n; i++) {
     53             a[i].x /= n;
     54         }
     55     }
     56     return;
     57 }
     58 
     59 int main() {
     60 
     61     scanf("%s%s", s, str);
     62     int n = strlen(s) - 1, m = strlen(str) - 1;
     63     LL b3 = 0;
     64     for(int i = 0; i <= n; i++) {
     65         a[i].x = (s[i] - 'a' + 1) * (s[i] - 'a' + 1);
     66     }
     67     for(int i = 0; i <= m; i++) {
     68         if(str[i] == '?') {
     69             b[m - i].x = 0;
     70         }
     71         else {
     72             b[m - i].x = (str[i] - 'a' + 1);
     73             b3 += (str[i] - 'a' + 1) * (str[i] - 'a' + 1) * (str[i] - 'a' + 1);
     74         }
     75     }
     76 
     77     int len = 2, lm = 1;
     78     while(len <= n + m) {
     79         len <<= 1;
     80         lm++;
     81     }
     82     for(int i = 1; i <= len; i++) {
     83         r[i] = (r[i >> 1] >> 1) | ((i & 1) << (lm - 1));
     84     }
     85 
     86     FFT(len, a, 1);
     87     FFT(len, b, 1);
     88     for(int i = 0; i <= len; i++) {
     89         a[i] = a[i] * b[i];
     90     }
     91     FFT(len, a, -1);
     92     for(int i = 0; i <= len; i++) {
     93         ans[i] = a[i].x;
     94     }
     95 
     96     for(int i = 0; i <= n; i++) {
     97         a[i].x = 2 * (s[i] - 'a' + 1);
     98         a[i].y = 0;
     99     }
    100     for(int i = n + 1; i <= len; i++) {
    101         a[i].x = a[i].y = 0;
    102     }
    103     for(int i = 0; i <= m; i++) {
    104         if(str[i] == '?') {
    105             b[m - i].x = 0;
    106         }
    107         else {
    108             b[m - i].x = (str[i] -'a' + 1) * (str[i] - 'a' + 1);
    109         }
    110         b[m - i].y = 0;
    111     }
    112     for(int i = m + 1; i <= len; i++) {
    113         b[i].x = b[i].y = 0;
    114     }
    115     FFT(len, a, 1);
    116     FFT(len, b, 1);
    117     for(int i = 0; i <= len; i++) {
    118         a[i] = a[i] * b[i];
    119     }
    120     FFT(len, a, -1);
    121     for(int i = 0; i <= len; i++) {
    122         ans[i] -= a[i].x;
    123     }
    124 
    125     for(int i = 0; i <= len; i++) {
    126         ans[i] += b3;
    127     }
    128 
    129     int temp = 0;
    130     for(int i = m; i <= n; i++) {
    131         temp += int(ans[i] + 0.5) == 0;
    132     }
    133     printf("%d
    ", temp);
    134     for(int i = m; i <= n; i++) {
    135         if(int(ans[i] + 0.5) == 0) {
    136             printf("%d
    ", i - m);
    137         }
    138     }
    139     return 0;
    140 }
    AC代码

    双倍经验:BZOJ4259

      1 #include  <cstdio>
      2 #include <cmath>
      3 #include <algorithm>
      4 #include <cstring>
      5 
      6 const int N = 300010;
      7 const double pi = 3.1415926535897932384626;
      8 
      9 struct cp {
     10     double x, y;
     11     cp(double X = 0, double Y = 0) {
     12         x = X;
     13         y = Y;
     14     }
     15     inline cp operator +(const cp &w) const {
     16         return cp(x + w.x, y + w.y);
     17     }
     18     inline cp operator -(const cp &w) const {
     19         return cp(x - w.x, y - w.y);
     20     }
     21     inline cp operator *(const cp &w) const {
     22         return cp(x * w.x - y * w.y, x * w.y + y * w.x);
     23     }
     24 }a[N << 2], b[N << 2];
     25 
     26 int r[N << 2];
     27 char s[N], str[N];
     28 double ans[N << 2];
     29 
     30 inline void FFT(int n, cp *a, int f) {
     31     for(int i = 0; i < n; i++) {
     32         if(i < r[i]) {
     33             std::swap(a[i], a[r[i]]);
     34         }
     35     }
     36 
     37     for(int len = 1; len < n; len <<= 1) {
     38         cp Wn(cos(pi / len), f * sin(pi / len));
     39         for(int i = 0; i < n; i += (len << 1)) {
     40             cp w(1, 0);
     41             for(int j = 0; j < len; j++) {
     42                 cp t = a[i + len + j] * w;
     43                 a[i + len + j] = a[i + j] - t;
     44                 a[i + j] = a[i + j] + t;
     45                 w = w * Wn;
     46             }
     47         }
     48     }
     49 
     50     if(f == -1) {
     51         for(int i = 0; i <= n; i++) {
     52             a[i].x /= n;
     53         }
     54     }
     55     return;
     56 }
     57 
     58 int main() {
     59     int m, n;
     60     scanf("%d%d", &m, &n);
     61     m--;
     62     n--;
     63     scanf("%s%s", str, s);
     64     for(int i = 0; i <= n; i++) {
     65         s[i] = (s[i] == '*' ? 0 : s[i] - 'a' + 1);
     66     }
     67     for(int i = 0; i <= m; i++) {
     68         str[i] = (str[i] == '*' ? 0 : str[i] - 'a' + 1);
     69     }
     70     int len = 2, lm = 1;
     71     while(len <= n + m) {
     72         len <<= 1;
     73         lm++;
     74     }
     75     for(int i = 1; i <= len; i++) {
     76         r[i] = (r[i >> 1] >> 1) | ((i & 1) << (lm - 1));
     77     }
     78 
     79     for(int i = 0; i <= n; i++) {
     80         a[i] = cp(1ll * s[i] * s[i] * s[i], 0);
     81     }
     82     for(int i = 0; i <= m; i++) {
     83         b[i] = cp(str[m - i], 0);
     84     }
     85     FFT(len, a, 1);
     86     FFT(len, b, 1);
     87     for(int i = 0; i <= len; i++) {
     88         a[i] = a[i] * b[i];
     89     }
     90     FFT(len, a, -1);
     91     for(int i = 0; i <= len; i++) {
     92         ans[i] = a[i].x;
     93     }
     94 
     95     for(int i = 0; i <= n; i++) {
     96         a[i] = cp(1ll * s[i] * s[i], 0);
     97     }
     98     for(int i = 0; i <= m; i++) {
     99         b[i] = cp(1ll * str[m - i] * str[m - i], 0);
    100     }
    101     for(int i = n + 1; i <= len; i++) {
    102         a[i] = cp(0, 0);
    103     }
    104     for(int i = m + 1; i <= len; i++) {
    105         b[i] = cp(0, 0);
    106     }
    107     FFT(len, a, 1);
    108     FFT(len, b, 1);
    109     for(int i = 0; i <= len; i++) {
    110         a[i] = a[i] * b[i];
    111     }
    112     FFT(len, a, -1);
    113     for(int i = 0; i <= len; i++) {
    114         ans[i] -= 2 * a[i].x;
    115     }
    116 
    117     for(int i = 0; i <= n; i++) {
    118         a[i] = cp(s[i], 0);
    119     }
    120     for(int i = 0; i <= m; i++) {
    121         b[i] = cp(1ll * str[m - i] * str[m - i] * str[m - i], 0);
    122     }
    123     for(int i = n + 1; i <= len; i++) {
    124         a[i] = cp(0, 0);
    125     }
    126     for(int i = m + 1; i <= len; i++) {
    127         b[i] = cp(0, 0);
    128     }
    129     FFT(len, a, 1);
    130     FFT(len, b, 1);
    131     for(int i = 0; i <= len; i++) {
    132         a[i] = a[i] * b[i];
    133     }
    134     FFT(len, a, -1);
    135     for(int i = 0; i <= len; i++) {
    136         ans[i] += a[i].x;
    137     }
    138 
    139     int temp = 0;
    140     for(int i = m; i <= n; i++) {
    141         temp += (int)(ans[i] + 0.5) == 0;
    142     }
    143     printf("%d
    ", temp);
    144     for(int i = m; i <= n; i++) {
    145         if((int)(ans[i] + 0.5) == 0) {
    146             printf("%d ", i - m + 1);
    147         }
    148     }
    149     return 0;
    150 }
    AC代码
  • 相关阅读:
    spark之手机基站定位数据的商圈分析
    spark之客户流失预测
    spark之AHP层次分析顾客价值得分
    Web-Attak系列教程第二季0x13讲——信息收集
    Web-Attak系列教程第二季0x12讲——HTTP的请求与响应格式
    Python编程系列教程第14讲——继承
    独孤九剑与黑客编程
    Python编程系列教程第15讲——多态
    Python编程系列教程第16讲——拷贝自身到系统目录
    再谈独孤九剑与黑客编程
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10244270.html
Copyright © 2011-2022 走看看