zoukankan      html  css  js  c++  java
  • [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
  • 相关阅读:
    ZOJ 2601 Warehouse Keeper
    POJ 2175 Evacuation Plan
    NYIST 1108 最低的惩罚
    二进制 与 十进制 互转
    javascript学习(9)——[设计模式]单例
    2013 Changsha Regional 一样的木板一样的气球
    muduo简化(1):Reactor的关键结构
    Oracle 11g New 热补丁
    跳转表实例
    [置顶] android 心跳包的分析
  • 原文地址:https://www.cnblogs.com/y7070/p/5001467.html
Copyright © 2011-2022 走看看