[BZOJ3207] 花神的嘲讽计划Ⅰ
哈希+可持久化线段树。
不需要统计区间和,只需要单点查询即可,主要是哈希难搞。
别忘了继承上一个点的信息。。。
sb哈希 : 直接把每个数字连在一起,中间用 '#' 或 '$' 链接,丢在map里,10920ms。
1 #include <bits/stdc++.h> 2 #define rep(i, a, b) for (int i = a; i <= b; i++) 3 #define REP(i, a, b) for (int i = a; i < b; i++) 4 #define drep(i, a, b) for (int i = a; i >= b; i--) 5 #define pb push_back 6 #define mp make_pair 7 #define xx first 8 #define yy second 9 using namespace std; 10 typedef long long i64; 11 typedef pair<int, int> pii; 12 const int inf = ~0U >> 1; 13 const i64 INF = ~0ULL >> 1; 14 //***************************** 15 16 const int maxn = 100005; 17 const int maxm = 36 * maxn; 18 19 int read() { 20 int l = 1, s = 0; 21 char ch = getchar(); 22 while (ch < '0' || ch > '9') { if (ch == '-') l = -1; ch = getchar(); } 23 while (ch >= '0' && ch <= '9') { s = (s << 1) + (s << 3) + ch - '0'; ch = getchar(); } 24 return l * s; 25 } 26 27 int hsh_cnt; 28 map<string, int> M; 29 string fuckit(int s, int k, char a[][15]) { 30 string str; 31 while (k--) { 32 for (int i = 0; a[s][i]; i++) str += a[s][i]; 33 s++; 34 str += '#'; 35 } 36 return str; 37 } 38 39 int nn; 40 char a[maxn][15]; 41 42 int Sum[maxm], root[maxm], Lson[maxm], Rson[maxm], ndtot; 43 void build(int x, int &y, int l, int r, int v) { 44 y = ++ndtot; 45 if (l == r) { 46 Sum[y] = Sum[x] + 1; 47 return; 48 } 49 int mid = l + r >> 1; 50 if (v <= mid) { 51 Rson[y] = Rson[x]; 52 build(Lson[x], Lson[y], l, mid, v); 53 } 54 else { 55 Lson[y] = Lson[x]; 56 build(Rson[x], Rson[y], mid + 1, r, v); 57 } 58 } 59 60 bool query(int x, int y, int l, int r, int v) { 61 if (l == r) { 62 return Sum[y] - Sum[x] > 0; 63 } 64 int mid = l + r >> 1; 65 if (v <= mid) return query(Lson[x], Lson[y], l, mid, v); 66 else return query(Rson[x], Rson[y], mid + 1, r, v); 67 } 68 69 char b[maxn][15]; 70 int main() { 71 int n, m, k; 72 n = read(), m = read(), k = read(); 73 nn = n; 74 rep(i, 1, n) scanf("%s", a[i]); 75 76 rep(i, 1, n - k + 1) { 77 string t = fuckit(i, k, a); 78 if (!M[t]) M[t] = ++hsh_cnt; 79 build(root[i - 1], root[i], 1, nn, M[t]); 80 } 81 while (m--) { 82 int l, r; l = read(), r = read(); rep(i, 1, k) scanf("%s", b[i]); 83 r -= k - 1; 84 string t = fuckit(1, k, b); 85 if (!M[t]) puts("Yes"); 86 else if (query(root[l - 1], root[r], 1, nn, M[t])) puts("No"); 87 else puts("Yes"); 88 } 89 }
老爷哈希 : 排序 + 二分,重新定义cmp函数来比较,4064ms。
1 #include <bits/stdc++.h> 2 #define rep(i, a, b) for (int i = a; i <= b; i++) 3 #define REP(i, a, b) for (int i = a; i < b; i++) 4 #define drep(i, a, b) for (int i = a; i >= b; i--) 5 #define pb push_back 6 #define mp make_pair 7 #define xx first 8 #define yy second 9 using namespace std; 10 typedef long long i64; 11 typedef pair<int, int> pii; 12 const int inf = ~0U >> 1; 13 const i64 INF = ~0ULL >> 1; 14 //***************************** 15 16 const int maxn = 100005; 17 const int maxm = 36 * maxn; 18 19 int read() { 20 int l = 1, s = 0; 21 char ch = getchar(); 22 while (ch < '0' || ch > '9') { if (ch == '-') l = -1; ch = getchar(); } 23 while (ch >= '0' && ch <= '9') { s = (s << 1) + (s << 3) + ch - '0'; ch = getchar(); } 24 return l * s; 25 } 26 27 int nn; 28 29 int Sum[maxm], root[maxm], Lson[maxm], Rson[maxm], ndtot; 30 void build(int x, int &y, int l, int r, int v) { 31 y = ++ndtot; 32 if (l == r) { 33 Sum[y] = Sum[x] + 1; 34 return; 35 } 36 int mid = l + r >> 1; 37 if (v <= mid) { 38 Rson[y] = Rson[x]; 39 build(Lson[x], Lson[y], l, mid, v); 40 } 41 else { 42 Lson[y] = Lson[x]; 43 build(Rson[x], Rson[y], mid + 1, r, v); 44 } 45 } 46 47 bool query(int x, int y, int l, int r, int v) { 48 if (l == r) { 49 return Sum[y] - Sum[x] > 0; 50 } 51 int mid = l + r >> 1; 52 if (v <= mid) return query(Lson[x], Lson[y], l, mid, v); 53 else return query(Rson[x], Rson[y], mid + 1, r, v); 54 } 55 56 int b[maxn], a[maxn]; 57 58 int k; 59 bool cmp1(int x, int y) { 60 REP(i, 0, k) { 61 if (a[x + i] < a[y + i]) return true; 62 if (a[x + i] > a[y + i]) return false; 63 } 64 return false; 65 } 66 bool diff(int x, int y) { 67 REP(i, 0, k) if (a[x + i] != a[y + i]) return 1; 68 return 0; 69 } 70 bool cmp2(int x) { 71 REP(i, 0, k) { 72 if (b[i + 1] < a[x + i]) return 0; 73 if (b[i + 1] > a[x + i]) return 1; 74 } 75 return 1; 76 } 77 bool equi(int x) { 78 REP(i, 0, k) if (a[x + i] != b[i + 1]) return 0; 79 return 1; 80 } 81 82 int G[maxn], c[maxn]; 83 int main() { 84 int n, m; 85 n = read(), m = read(), k = read(); 86 rep(i, 1, n) scanf("%d", &a[c[i] = i]); 87 88 sort(c + 1, c + 1 + n, cmp1); 89 int idx; 90 G[c[1]] = idx = 1; 91 rep(i, 2, n) G[c[i]] = idx += diff(c[i - 1], c[i]); 92 93 rep(i, 1, n - k + 1) 94 build(root[i - 1], root[i], 1, idx, G[i]); 95 96 while (m--) { 97 int l, r; l = read(), r = read(); 98 rep(i, 1, k) scanf("%d", &b[i]); 99 r -= k - 1; 100 int low = 0, high = n + 1; 101 while (low < high - 1) { 102 int mid = low + high >> 1; 103 if (cmp2(c[mid])) low = mid; 104 else high = mid; 105 } 106 if (!equi(c[low])) puts("Yes"); 107 else if (query(root[l - 1], root[r], 1, idx, G[c[low]])) puts("No"); 108 else puts("Yes"); 109 } 110 }