[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 }
View Code

 

  老爷哈希 : 排序 + 二分,重新定义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 }
View Code

 

posted @ 2015-11-27 18:18  y7070  阅读(229)  评论(0编辑  收藏  举报