• [Bzoj1014][JSOI2008]火星人prefix(无旋Treap&hash)


    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1014

    因为涉及到增加和修改,所以后缀数组就被pass掉了,想到的就是平衡树维护hash值,查询的时候就是二分相同的长度来比较,修改就是删除再增加。

    这里使用的是无旋Treap

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 typedef unsigned int ull;
      5 const int maxn = 200010;
      6 int Siz[maxn], ls[maxn], rs[maxn], pos[maxn], val[maxn], root, cnt;
      7 ull Hash[maxn], w[maxn];
      8 inline void up(int x) {
      9     Siz[x] = Siz[ls[x]] + Siz[rs[x]] + 1;
     10     w[x] = w[ls[x]] * Hash[Siz[rs[x]] + 1] + Hash[Siz[rs[x]]] * val[x] + w[rs[x]];
     11 }
     12 inline void split_size(int x, int siz, int &A, int &B) {
     13     if (x == 0)return (void)(A = B = 0);
     14     if (siz <= Siz[ls[x]])
     15         B = x, split_size(ls[x], siz, A, ls[x]);
     16     else
     17         A = x, split_size(rs[x], siz - Siz[ls[x]] - 1, rs[x], B);
     18     up(x);
     19 }
     20 inline int Merge(int A, int B) {
     21     if (A == 0 || B == 0)return A | B;
     22     int ans;
     23     if (pos[A] > pos[B])ans = A, rs[A] = Merge(rs[A], B);
     24     else ans = B, ls[B] = Merge(A, ls[B]);
     25     up(ans);
     26     return ans;
     27 }
     28 inline void insert(int x, char v) {
     29     int A, B;
     30     split_size(root, x, A, B);
     31     cnt++;
     32     w[cnt] = val[cnt] = v - 'a' + 1;
     33     Siz[cnt] = 1;
     34     pos[cnt] = rand();
     35     root = Merge(Merge(A, cnt), B);
     36 }
     37 inline void Delete(int x) {
     38     int A, B, C, D;
     39     split_size(root, x, A, B);
     40     split_size(A, x - 1, C, D);
     41     D = Merge(ls[D], rs[D]);
     42     root = Merge(Merge(C, D), B);
     43 }
     44 inline ull query(int l, int r) {
     45     int A, B, C, D;
     46     ull ans;
     47     split_size(root, l - 1, A, B);
     48     split_size(B, r - l + 1, C, D);
     49     ans = w[C];
     50     root = Merge(A, Merge(C, D));
     51     return ans;
     52 }
     53 inline bool check(int x, int y, int len) {
     54     return query(x, x + len - 1) == query(y, y + len - 1);
     55 }
     56 inline int read() {
     57     int x = 0, f = 1; char c = getchar();
     58     for (; !isdigit(c); c = getchar()) if (c == '-') f = -1;
     59     for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; return x * f;
     60 }
     61 inline char cread() {
     62     char c = getchar();
     63     for (; !isalpha(c); c = getchar()); return c;
     64 }
     65 inline void reads(string& s) {
     66     char c = getchar();
     67     for (; !isalpha(c); c = getchar()); s = " ";
     68     for (; isalpha(c); c = getchar()) s += c;
     69 }
     70 string s;
     71 int main() {
     72     reads(s);
     73     int n = s.size() - 1, m;
     74     m = read();
     75     Hash[0] = 1;
     76     for (int i = 1; i < maxn; i++)
     77         Hash[i] = Hash[i - 1] * 131;
     78     for (int i = 1; i <= n; i++)
     79         insert(i, s[i]);
     80     while (m--) {
     81         char opt;
     82         int x, y;
     83         opt = cread();
     84         if (opt == 'Q') {
     85             x = read(), y = read();
     86             int l = 0, r = min(n - x, n - y) + 1, ans;
     87             while (l <= r) {
     88                 int mid = l + r >> 1;
     89                 if (check(x, y, mid)) {
     90                     ans = mid;
     91                     l = mid + 1;
     92                 }
     93                 else
     94                     r = mid - 1;
     95             }
     96             printf("%d
    ", ans);
     97         }
     98         else if (opt == 'R') {
     99             x = read(), opt = cread();
    100             Delete(x);
    101             insert(x - 1, opt);
    102         }
    103         else {
    104             x = read(), opt = cread();
    105             n++;
    106             insert(x, opt);
    107         }
    108     }
    109     return 0;
    110 }
    View Code
  • 相关阅读:
    剑指offer-删除链表中重复的结点
    剑指offer-矩阵中的路径
    剑指offer-旋转数组的最小数字
    剑指offer-用两个栈实现队列
    剑指offer-二叉树的下一个节点
    剑指offer-从尾到头打印链表
    SSM整合所需jar包
    剑指offer-树中两个节点的最低公共祖先
    剑指offer-判断是否是平衡二叉树
    剑指offer-二叉树的深度
  • 原文地址:https://www.cnblogs.com/sainsist/p/11126367.html
Copyright © 2020-2023  润新知