UVA 11996 Jewel Magic —— splay序列的分裂与合并LCP的哈希算法
Posted kiraa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA 11996 Jewel Magic —— splay序列的分裂与合并LCP的哈希算法相关的知识,希望对你有一定的参考价值。
1 #include <cstdio> 2 #include <cstdlib> 3 #include <iostream> 4 #include <algorithm> 5 #include <vector> 6 7 using namespace std; 8 9 typedef unsigned long long ull; 10 const int x = 123; 11 const int maxn = 4e5 + 10; 12 13 ull xp[maxn]; 14 int n, m; 15 struct Node { 16 Node* ch[2]; 17 int r, v, s; 18 int val; 19 ull Hush[2]; 20 int flip; 21 Node(int v1, int v2): v(v1), val(v2) { 22 r = rand(); 23 s = 1; 24 ch[0] = ch[1] = NULL; 25 flip = 0; 26 Hush[0] = Hush[1] = val; 27 } 28 bool cmp(const int &x) const { 29 if(x == v) return -1; 30 return x < v ? 0 : 1; 31 } 32 void maintain() { 33 s = 1; 34 Hush[0] = Hush[1] = val; 35 if(ch[0] != NULL) s += ch[0]->s, Hush[0] = ch[0]->Hush[ch[0]->flip] + val*xp[ch[0]->s]; 36 if(ch[1] != NULL) Hush[0] += (ch[1]->Hush[ch[1]->flip])*xp[s], s += ch[1]->s; 37 int s2 = 1; 38 if(ch[1] != NULL) s2 += ch[1]->s, Hush[1] = ch[1]->Hush[(ch[1]->flip)^1] + val*xp[ch[1]->s]; 39 if(ch[0] != NULL) Hush[1] += (ch[0]->Hush[(ch[0]->flip)^1])*xp[s2]; 40 } 41 void pushdown() { 42 if(flip) { 43 flip = 0; 44 swap(ch[0], ch[1]); 45 if(ch[0] != NULL) ch[0]->flip = !ch[0]->flip; 46 if(ch[1] != NULL) ch[1]->flip = !ch[1]->flip; 47 } 48 } 49 }; 50 51 void rotate(Node* &o, int d) { 52 Node* k = o->ch[d^1]; o->ch[d^1] = k->ch[d]; k->ch[d] = o; 53 o->maintain(); k->maintain(); o = k; 54 } 55 56 void insert(Node* &o, int x, int val) { 57 if(o == NULL) o = new Node(x, val); 58 else { 59 int d = o->cmp(x); 60 insert(o->ch[d], x, val); 61 if(o->ch[d]->r > o->r) rotate(o, d^1); 62 } 63 o->maintain(); 64 } 65 void splay(Node* &o, int k) { 66 o->pushdown(); 67 int s = o->ch[0] == NULL ? 0 : o->ch[0]->s; 68 int d = k <= s ? 0 : (k == s+1? -1 : 1); 69 if(d == 1) k -= s+1; 70 if(d != -1) { 71 splay(o->ch[d], k); 72 rotate(o, d^1); 73 } 74 } 75 76 Node * merge(Node* left, Node* right) { 77 splay(left, left->s); 78 left->ch[1] = right; 79 left->maintain(); 80 return left; 81 } 82 void split(Node* o, int k , Node* &left, Node* &right) { 83 splay(o, k); 84 left = o; 85 right = o->ch[1]; 86 o->ch[1] = NULL; 87 left->maintain(); 88 } 89 90 void oper1(Node* &o, int p, int c) { 91 Node* left, *right; 92 Node* node = new Node(p+1, c); 93 split(o, p+1, left, right); 94 o = merge(merge(left, node), right); 95 } 96 void oper2(Node* &o, int p) { 97 Node* left, *mid, *right; 98 split(o, p, left, mid); 99 split(mid, 1, mid, right); 100 o = merge(left, right); 101 } 102 void oper3(Node* &o, int p1, int p2) { 103 Node *left, *mid, *right; 104 split(o, p1, left, mid); 105 split(mid, p2-p1+1, mid, right); 106 mid->flip ^= 1; 107 o = merge(merge(left, mid), right); 108 } 109 ull Hush_val(Node* &o, int p, int L) { 110 Node *left, *mid, *right; 111 split(o, p, left, mid); 112 split(mid, L, mid, right); 113 ull ans = mid->Hush[mid->flip]; 114 o = merge(merge(left, mid), right); 115 return ans; 116 } 117 int oper4(Node* &o, int p1, int p2) { 118 int L = 0, R = min(n-p1+1, n-p2+1); 119 while(L < R) { 120 int M = R - (R-L)/2; 121 int l1 = Hush_val(o, p1, M), l2 = Hush_val(o, p2, M); 122 if(l1 == l2) L = M; 123 else R = M-1; 124 } 125 return L; 126 } 127 char s[maxn]; 128 int main() { 129 xp[0] = 1; 130 for(int i = 1; i < maxn; i++) xp[i] = xp[i-1]*x; 131 while(scanf("%d%d", &n, &m) == 2) { 132 scanf("%s", s); 133 Node* root = new Node(0, 0); 134 for(int i = 0; i < n; i++) { 135 int c = s[i] - ‘0‘; 136 insert(root, i+1, c); 137 } 138 for(int i = 0; i < m; i++) { 139 int id, p1, p2; 140 scanf("%d", &id); 141 if(id == 1) { 142 scanf("%d%d", &p1, &p2); 143 oper1(root, p1, p2); 144 n++; 145 } 146 if(id == 2) { 147 scanf("%d", &p1); 148 oper2(root, p1); 149 n--; 150 } 151 if(id == 3) { 152 scanf("%d%d", &p1, &p2); 153 oper3(root, p1, p2); 154 } 155 if(id == 4) { 156 scanf("%d%d", &p1, &p2); 157 int ans = oper4(root, p1, p2); 158 printf("%d\n", ans); 159 } 160 } 161 } 162 return 0; 163 }
以上是关于UVA 11996 Jewel Magic —— splay序列的分裂与合并LCP的哈希算法的主要内容,如果未能解决你的问题,请参考以下文章
UVa 11996 Jewel Magic (splay + Hash + 二分)
UVA - 11996 可持久化Treap 维护Hash(仅观赏)