S+6-字符串
A. 文本校对
- 暴力HASH就好了1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95const int N = 1e6 + 5, base = 19260817, mod = 998244353; 
 int n, m, h[N], pw[N], inv[N], now[N];
 string s;
 ll qpow(int x, int y)
 {
 ll res = 0;
 while (y)
 {
 if (y & 1)
 res = res * x % mod;
 x = x * x % mod;
 y >>= 1;
 }
 return res;
 }
 void insert(int pos, int x)
 {
 string ss = " ";
 for (int i = 1; i < pos; i++)
 ss += s[i];
 ss += x;
 for (int i = pos; i <= n; i++)
 ss += s[i];
 for (int i = 1; i <= n; i++) {
 if (now[i] >= pos)
 now[i]++;
 }
 n++;
 s = ss;
 for (int i = 1; i <= n; i++)
 {
 h[i] = (h[i - 1] * base % mod + s[i] - 'a') % mod;
 }
 }
 int query(int l, int r)
 {
 return (h[r] - h[l - 1] * pw[r - l + 1] % mod + mod) % mod;
 }
 int check(int x, int i, int j)
 {
 return query(i, i + x - 1) == query(j, j + x - 1);
 }
 signed main()
 {
 IOS;
 cin >> s >> m;
 s = ' ' + s;
 n = s.size() - 1;
 pw[0] = 1;
 for (int i = 1; i < N; i++)
 {
 pw[i] = pw[i - 1] * base % mod;
 }
 for (int i = 1; i <= n; i++)
 {
 now[i] = i;
 h[i] = (h[i - 1] * base % mod + s[i] - 'a') % mod;
 }
 while (m--)
 {
 char op, x;
 cin >> op;
 if (op == 'I')
 {
 char x;
 int p;
 cin >> x >> p;
 p = min(p, n - 1);
 insert(p, x);
 }
 else
 {
 int i, j;
 cin >> i >> j;
 int l = 1, r = min(n - now[i] + 1, n - now[j] + 1), res = 0;
 while (l <= r)
 {
 int mid = (l + r) / 2;
 if (check(mid, now[i], now[j]))
 {
 l = mid + 1;
 res = mid;
 }
 else
 {
 r = mid - 1;
 }
 }
 cout << res << endl;
 }
 }
 return 0;
 }
B. 最长回文
- 可以马拉车直接做1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45char chs[22000005]; 
 int p[22000005], cnt, ans;
 void manacher()
 {
 int mx = 0, mid = 0;
 for (int i = 0; i <= cnt; i++)
 {
 if (i < mx)
 {
 p[i] = min(mx - i, p[mid * 2 - i]);
 }
 else
 {
 p[i] = 1;
 }
 while (i + p[i] <= cnt && i - p[i] >= 0 && chs[i + p[i]] == chs[i - p[i]])
 {
 p[i]++;
 }
 if (i + p[i] > mx)
 {
 mx = i + p[i];
 mid = i;
 }
 ans = max(p[i], ans);
 }
 }
 int main()
 {
 int n;
 cin >> n;
 getchar();
 getchar();
 char ch = getchar();
 chs[0] = '#';
 while (ch >= 'a' && ch <= 'z')
 {
 chs[++cnt] = ch;
 chs[++cnt] = '#';
 ch = getchar();
 }
 manacher();
 printf("%d\n", ans - 1);
 return 0;
 }
- 二分+HASH1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58typedef unsigned long long ull; 
 typedef long long ll;
 constexpr int N = 1145141, base = 127;
 int n, ans;
 ull h[N], hRev[N], p[N];
 char s[N], sRev[N];
 ull getHashAll(char s[], int len) {
 ull ret = 0;
 for (int i = 1; i <= len; i++)
 ret = base * ret + (ull)s[i];
 return ret;
 }
 void getHashSeq(char s[], int len, ull h[]) {
 h[0] = 0;
 for (int i = 1; i <= len; i++)
 h[i] = h[i - 1] * base + s[i];
 }
 void getP(int len) {
 p[0] = 1;
 for (int i = 1; i <= len; i++)
 p[i] = p[i - 1] * base;
 }
 ull getSubHash(ull h[], int l, int r) {
 return h[r] - h[l - 1] * p[r - l + 1];
 }
 int main() {
 scanf("%d\n%s", &n, s + 1);
 for (int i = 1; i <= n; i++)
 sRev[n - i + 1] = s[i];
 getHashSeq(s, n, h);
 getHashSeq(sRev, n, hRev);
 getP(n + 1);
 for (int i = 1; i <= n; i++) {
 int l = 0, r = min(i - 1, n - i), mid;
 while (l <= r) {
 mid = (l + r) >> 1;
 if (getSubHash(h, i - mid, i - 1) == getSubHash(hRev, (n - i + 1) - mid, n - i)) {
 ans = max(ans, (mid << 1) | 1);
 l = mid + 1;
 } else
 r = mid - 1;
 }
 }
 for (int i = 1; i < n; i++) {
 int l = 1, r = min(i, n - i), mid;
 while (l <= r) {
 mid = (l + r) >> 1;
 if (getSubHash(h, i - mid + 1, i) == getSubHash(hRev, n - i + 1 - mid, n - i)) {
 ans = max(ans, mid << 1);
 l = mid + 1;
 } else
 r = mid - 1;
 }
 }
 printf("%d", ans);
 return 0;
 }
C. 二维匹配
- 二维HASH1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51/* 
 二维hash板子
 先对整体取哈希,把每个大小为 A×B 的存入 unordered_map;然后对每个子矩阵取哈希,判断是否在 map 中即可。时间复杂度 O(n^2)。
 g_{x, y}=(a_{x, y}+g_{x−1, y} × p2 + g_{x, y−1} × p1 − g{x−1, y−1} × p1 × p2) mod p
 H(x1,y1,x2,y2)=(H(1,1,x2,y2)−H(1,1,x1−1,y2)×p2x2−x1+1−H(1,1,x2,y1−1)×p1y2−y1+1+H(1,1,x1−1,y1−1)×p2x2−x1+1×p1y2−y1+1)modM
 */
 using namespace std;
 const int base1 = 131, base2 = 13331;
 long long n, m, q, a, b, mt[5010][5010], s[5010][5010], l1[5010], l2[5010];
 map<long long, bool> HASH;
 void handle(long long ll, long long rr) {
 for (int i = 1; i <= ll; i++) {
 for (int j = 1; j <= rr; j++) {
 char s;
 cin >> s;
 mt[i][j] = s - '0' + 1;
 }
 }
 for (int i = 1; i <= rr; i++) {
 l1[i] = l1[i - 1] * base1;
 l2[i] = l2[i - 1] * base2;
 }
 for (int i = 1; i <= ll; i++) {
 for (int j = 1; j <= rr; j++) {
 s[i][j] = s[i][j - 1] * base1 + mt[i][j];
 }
 }
 for (int i = 1; i <= ll; i++) {
 for (int j = 1; j <= rr; j++) {
 s[i][j] += s[i - 1][j] * base2;
 }
 }
 }
 int main() {
 l1[0] = l2[0] = 1;
 cin >> n >> m >> a >> b;
 handle(n, m);
 for (int i = a; i <= n; i++) {
 for (int j = b; j <= m; j++) {
 HASH[s[i][j] - s[i - a][j]*l2[a] - s[i][j - b]*l1[b] + s[i - a][j - b]*l2[a]*l1[b]] = 1;
 }
 }
 cin >> q;
 for (int k = 1; k <= q; k++) {
 handle(a, b);
 if (HASH[s[a][b]])cout << 1 << endl;
 else cout << 0 << endl;
 }
 return 0;
 }
- 一个没优化过的AC自动机1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62int n, m, trie[410][26], fail[410], now, dep[410], state[410]; 
 bool late[410];
 queue<int> q;
 void insert(string s) {
 int len = s.length(), p = 0;
 for (int i = 0; i < len; i++) {
 if (!trie[p][s[i] - 'a'])
 trie[p][s[i] - 'a'] = ++now;
 dep[trie[p][s[i] - 'a']] = dep[p] + 1;
 p = trie[p][s[i] - 'a'];
 }
 late[p] = true;
 }
 void init() {
 for (int i = 0; i < 26; i++)
 if (trie[0][i])
 q.push(trie[0][i]);
 while (!q.empty()) {
 int x = q.front();
 q.pop();
 int Fail = fail[x];
 state[x] = state[Fail];
 if (late[x])
 state[x] |= (1 << dep[x]);
 for (int i = 0; i < 26; i++) {
 if (trie[x][i])
 fail[trie[x][i]] = trie[Fail][i], q.push(trie[x][i]);
 else
 trie[x][i] = trie[Fail][i];
 }
 }
 }
 int query(string t) {
 int len = t.length(), p = 0, ans = 0;
 unsigned predigit = 1;
 for (int i = 0; i < len; i++) {
 int tp = t[i] - 'a';
 p = trie[p][tp];
 predigit <<= 1;
 if (predigit & state[p])
 predigit |= 1, ans = max(ans, i + 1);
 }
 return ans;
 }
 int main() {
 ios::sync_with_stdio(false);
 cin.tie(0);
 cout.tie(0);
 cin >> n >> m;
 for (int i = 1; i <= n; i++) {
 string s;
 cin >> s;
 insert(s);
 }
 init();
 for (int i = 1; i <= m; i++) {
 string t;
 cin >> t;
 cout << query(t) << "\n";
 }
 return 0;
 }
F. 两段异或和
- 01trie去找最大异或就好了1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43const int N=4e5+10; 
 int n,tr[N*32][2],a[N],s[N],l[N],r[N],tot,ans;
 void insert(int x){
 int u=0;
 for(int i=30;i>=0;i--){
 int c=(x>>i)&1;
 if(!tr[u][c]) tr[u][c]=++tot;
 u=tr[u][c];
 }
 }
 int query(int x){
 int u=0,res=0;
 for(int i=30;i>=0;i--){
 int c=(x>>i)&1;
 if(tr[u][c^1]){
 res+=(1<<i);
 u=tr[u][c^1];
 }
 else u=tr[u][c];
 }
 return res;
 }
 signed main(){
 ios::sync_with_stdio(0);
 cin>>n;
 for(int i=1;i<=n;i++) cin>>a[i];
 for(int i=1;i<=n;i++) s[i]=s[i-1]^a[i];
 insert(0);
 for(int i=1;i<=n;i++){
 l[i]=max(l[i-1],query(s[i]));
 insert(s[i]);
 }
 memset(tr,0,sizeof tr);
 tot=0;
 for(int i=n;i>=1;i--) s[i]=s[i+1]^a[i];
 insert(0);
 for(int i=n;i>=1;i--){
 r[i]=max(r[i+1],query(s[i]));
 insert(s[i]);
 }
 for(int i=1;i<n;i++) ans=max(ans,l[i]+r[i+1]);
 cout<<ans<<'\n';
 }
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ysmmm的快乐小屋!

