JZOJ 5815. 【省选模拟2018.8.14】回文串


假的数据范围……第五个大样例是$\mid A \mid = 10^6$……

把B串翻转过来,就相当于每次给定A和B的两个后缀,然后统计这个的前缀数量:$lcp \gt 0$,且去掉$lcp$后的剩余部分最多只有一个是非空的,且是一个回文串

hash处理+前缀和提取区间+hash求lcp就行了……

  1 %:pragma GCC optimize(2)
  2 %:pragma GCC optimize(3)
  3 %:pragma GCC optimize("Ofast")
  4 %:pragma GCC optimize("inline")
  5 %:pragma GCC optimize("-fgcse")
  6 %:pragma GCC optimize("-fgcse-lm")
  7 %:pragma GCC optimize("-fipa-sra")
  8 %:pragma GCC optimize("-ftree-pre")
  9 %:pragma GCC optimize("-ftree-vrp")
 10 %:pragma GCC optimize("-fpeephole2")
 11 %:pragma GCC optimize("-ffast-math")
 12 %:pragma GCC optimize("-fsched-spec")
 13 %:pragma GCC optimize("unroll-loops")
 14 %:pragma GCC optimize("-falign-jumps")
 15 %:pragma GCC optimize("-falign-loops")
 16 %:pragma GCC optimize("-falign-labels")
 17 %:pragma GCC optimize("-fdevirtualize")
 18 %:pragma GCC optimize("-fcaller-saves")
 19 %:pragma GCC optimize("-fcrossjumping")
 20 %:pragma GCC optimize("-fthread-jumps")
 21 %:pragma GCC optimize("-funroll-loops")
 22 %:pragma GCC optimize("-fwhole-program")
 23 %:pragma GCC optimize("-freorder-blocks")
 24 %:pragma GCC optimize("-fschedule-insns")
 25 %:pragma GCC optimize("inline-functions")
 26 %:pragma GCC optimize("-ftree-tail-merge")
 27 %:pragma GCC optimize("-fschedule-insns2")
 28 %:pragma GCC optimize("-fstrict-aliasing")
 29 %:pragma GCC optimize("-fstrict-overflow")
 30 %:pragma GCC optimize("-falign-functions")
 31 %:pragma GCC optimize("-fcse-skip-blocks")
 32 %:pragma GCC optimize("-fcse-follow-jumps")
 33 %:pragma GCC optimize("-fsched-interblock")
 34 %:pragma GCC optimize("-fpartial-inlining")
 35 %:pragma GCC optimize("no-stack-protector")
 36 %:pragma GCC optimize("-freorder-functions")
 37 %:pragma GCC optimize("-findirect-inlining")
 38 %:pragma GCC optimize("-fhoist-adjacent-loads")
 39 %:pragma GCC optimize("-frerun-cse-after-loop")
 40 %:pragma GCC optimize("inline-small-functions")
 41 %:pragma GCC optimize("-finline-small-functions")
 42 %:pragma GCC optimize("-ftree-switch-conversion")
 43 %:pragma GCC optimize("-foptimize-sibling-calls")
 44 %:pragma GCC optimize("-fexpensive-optimizations")
 45 %:pragma GCC optimize("-funsafe-loop-optimizations")
 46 %:pragma GCC optimize("inline-functions-called-once")
 47 %:pragma GCC optimize("-fdelete-null-pointer-checks")
 48 
 49 #include <bits/stdc++.h>
 50 using namespace std;
 51 const int N = 1e6 + 10, base = 137, p = 998244353;
 52 typedef long long ll;
 53 int n, m, q;
 54 char s[N], t[N];
 55 ll f[N], g[N], pp[N], ps[N], qp[N], qs[N], pw[N];
 56 
 57 void calc(char *s, ll *f, ll *pre, ll *sub, int n) {
 58     for(int i = 1 ; i <= n ; ++ i) pre[i] = (pre[i - 1] * base + s[i]) % p;
 59     
 60     for(int i = n ; i >= 1 ; -- i) sub[i] = (sub[i + 1] * base + s[i]) % p;
 61     
 62     // 1
 63     for(int i = 1 ; i <= n ; ++ i) {
 64         int l = 0, r = min(i - 1, n - i), len = 0;
 65         while(l <= r) {
 66             int mid = (l + r) >> 1;
 67             // [i - mid .. i] [i .. i + len]
 68             ll x = (pre[i] - pre[i - mid - 1] * pw[mid + 1] % p) % p;
 69             ll y = (sub[i] - sub[i + mid + 1] * pw[mid + 1] % p) % p;
 70             x = (x + p) % p;
 71             y = (y + p) % p;
 72             if(x == y) len = mid, l = mid + 1;
 73             else r = mid - 1;
 74         }
 75         // [i - len .. i] [i .. i + len]
 76         f[i - len] ++;
 77         f[i + 1] --;
 78     }
 79     
 80     // 2
 81     for(int i = 1 ; i < n ; ++ i) {
 82         if(s[i] != s[i + 1]) continue;
 83         int l = 0, r = min(i - 1, n - i - 1), len = 0;
 84         while(l <= r) {
 85             int mid = (l + r) >> 1;
 86             ll x = (pre[i] - pre[i - mid - 1] * pw[mid + 1] % p) % p;
 87             ll y = (sub[i + 1] - sub[i + 1 + mid + 1] * pw[mid + 1] % p) % p;
 88             x = (x + p) % p;
 89             y = (y + p) % p;
 90             if(x == y) len = mid, l = mid + 1;
 91             else r = mid - 1;
 92         }
 93         // [i - len, i] [i + 1, i + 1 + len]
 94         f[i - len] ++;
 95         f[i + 1] --;
 96     }
 97     for(int i = 1 ; i <= n ; ++ i) f[i] += f[i - 1];
 98     for(int i = 1 ; i <= n ; ++ i) f[i] += f[i - 1];
 99     f[n + 1] = f[n];
100 }
101 
102 ll sol(int x, int y) {
103     if(s[x] != t[y]) return 0;
104     int l = 0, r = min(n - x, m - y), len = 0;
105     while(l <= r) {
106         int mid = (l + r) >> 1;
107         ll a = (ps[x] - ps[x + mid + 1] * pw[mid + 1] % p) % p;
108         ll b = (qs[y] - qs[y + mid + 1] * pw[mid + 1] % p) % p;
109         a = (a + p) % p;
110         b = (b + p) % p;
111         if(a == b) len = mid, l = mid + 1;
112         else r = mid - 1;
113     }
114     return f[x + len + 1] - f[x] + g[y + len + 1] - g[y] + len + 1;
115 }
116 
117 int main() {
118     freopen("palindrome.in", "r", stdin);
119     freopen("palindrome.out", "w", stdout);
120     scanf("%*s");
121     scanf("%s%s", s + 1, t + 1);
122     n = strlen(s + 1), m = strlen(t + 1);
123     reverse(t + 1, t + 1 + m);
124     for(int i = pw[0] = 1 ; i <= max(n, m) ; ++ i) pw[i] = pw[i - 1] * base % p;
125     calc(s, f, pp, ps, n);
126     calc(t, g, qp, qs, m);
127     scanf("%d", &q);
128     for(int i = 1, x, y ; i <= q ; ++ i) {
129         scanf("%d%d", &x, &y);
130         printf("%lld\n", sol(x, y));
131     }
132 }
JZOJ 5815. 【省选模拟2018.8.14】回文串

转载于:https://www.cnblogs.com/KingSann/articles/9480331.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值