• WF 2019


    A

    把价格相同的瓷砖分为一类然后按序贪心匹配,注意要用小的集合匹配大的集合。

      1 #include <bits/stdc++.h>
      2 
      3 #define IL __inline__ __attribute__((always_inline))
      4 
      5 #define For(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++ i)
      6 #define FOR(i, a, b) for (int i = (a), i##end = (b); i < i##end; ++ i)
      7 #define Rep(i, a, b) for (int i = (a), i##end = (b); i >= i##end; -- i)
      8 #define REP(i, a, b) for (int i = (a) - 1, i##end = (b); i >= i##end; -- i)
      9 
     10 typedef long long LL;
     11 
     12 template <class T>
     13 IL bool chkmax(T &a, const T &b) {
     14   return a < b ? ((a = b), 1) : 0;
     15 }
     16 
     17 template <class T>
     18 IL bool chkmin(T &a, const T &b) {
     19   return a > b ? ((a = b), 1) : 0;
     20 }
     21 
     22 template <class T>
     23 IL T mymax(const T &a, const T &b) {
     24   return a > b ? a : b;
     25 }
     26 
     27 template <class T>
     28 IL T mymin(const T &a, const T &b) {
     29   return a < b ? a : b;
     30 }
     31 
     32 template <class T>
     33 IL T myabs(const T &a) {
     34   return a > 0 ? a : -a;
     35 }
     36 
     37 const int INF = 0X3F3F3F3F;
     38 const double EPS = 1E-8, PI = acos(-1.0);
     39 
     40 #define DEBUG(...) fprintf(stderr, __VA_ARGS__)
     41 #define OK DEBUG("Passing [%s] in LINE %d...
    ", __FUNCTION__, __LINE__)
     42 
     43 const int MAXN = 500000 + 5;
     44 
     45 struct Item {
     46   int h, val, idx;
     47 
     48   friend bool operator<(const Item &a, const Item &b) {
     49     return a.h == b.h ? a.idx < b.idx : a.h < b.h;
     50   }
     51 } a[MAXN], b[MAXN];
     52 
     53 std::pair<int, int> answer[MAXN];
     54 
     55 IL void GG() {
     56   puts("impossible");
     57   exit(0);
     58 }
     59 
     60 int main() {
     61   int n;
     62   scanf("%d", &n);
     63   For(i, 1, n) {
     64     a[i].idx = b[i].idx = i;
     65   }
     66   auto comp = [](const Item &a, const Item &b) {
     67     return a.val < b.val;
     68   };
     69   For(i, 1, n) {
     70     scanf("%d", &b[i].val);
     71   }
     72   For(i, 1, n) {
     73     scanf("%d", &b[i].h);
     74   }
     75   std::sort(b + 1, b + n + 1, comp);
     76   For(i, 1, n) {
     77     scanf("%d", &a[i].val);
     78   }
     79   For(i, 1, n) {
     80     scanf("%d", &a[i].h);
     81   }
     82   std::sort(a + 1, a + n + 1, comp);
     83   std::set<Item> x, y;
     84   int cur_x = 1, cur_y = 1;
     85   For(i, 1, n) {
     86     if (x.empty()) {
     87       int cost = a[cur_x].val;
     88       for (; a[cur_x].val == cost; x.insert(a[cur_x ++]));
     89     }
     90     if (y.empty()) {
     91       int cost = b[cur_y].val;
     92       for (; b[cur_y].val == cost; y.insert(b[cur_y ++]));
     93     }
     94     if (x.size() <= y.size()) {
     95       auto dx = x.begin(), dy = y.upper_bound({dx->h, dx->val, INF});
     96       if (dy == y.end()) {
     97         GG();
     98       }
     99       answer[i] = {dx->idx, dy->idx};
    100       x.erase(dx), y.erase(dy);
    101     } else {
    102       auto dy = y.begin(), dx = x.lower_bound({dy->h, dy->val, 0});
    103       if (dx == x.begin()) {
    104         GG();
    105       }
    106       -- dx;
    107       answer[i] = {dx->idx, dy->idx};
    108       x.erase(dx), y.erase(dy);
    109     }
    110   }
    111   For(i, 1, n) {
    112     printf("%d ", answer[i].second);
    113   }
    114   puts("");
    115   For(i, 1, n) {
    116     printf("%d ", answer[i].first);
    117   }
    118   puts("");
    119   return 0;
    120 }
    View Code

    B

    把半圆剖成两半,对每个点求出左半圆和右半圆最远能到什么地方,这样就可以$O(1)$判断一个拱形是否合法,然后$O(n^2) ext{dp}$即可。

     1 #include <bits/stdc++.h>
     2 
     3 #define IL __inline__ __attribute__((always_inline))
     4 
     5 #define For(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++ i)
     6 #define FOR(i, a, b) for (int i = (a), i##end = (b); i < i##end; ++ i)
     7 #define Rep(i, a, b) for (int i = (a), i##end = (b); i >= i##end; -- i)
     8 #define REP(i, a, b) for (int i = (a) - 1, i##end = (b); i >= i##end; -- i)
     9 
    10 typedef long long LL;
    11 
    12 template <class T>
    13 IL bool chkmax(T &a, const T &b) {
    14   return a < b ? ((a = b), 1) : 0;
    15 }
    16 
    17 template <class T>
    18 IL bool chkmin(T &a, const T &b) {
    19   return a > b ? ((a = b), 1) : 0;
    20 }
    21 
    22 template <class T>
    23 IL T mymax(const T &a, const T &b) {
    24   return a > b ? a : b;
    25 }
    26 
    27 template <class T>
    28 IL T mymin(const T &a, const T &b) {
    29   return a < b ? a : b;
    30 }
    31 
    32 template <class T>
    33 IL T myabs(const T &a) {
    34   return a > 0 ? a : -a;
    35 }
    36 
    37 const int INF = 0X3F3F3F3F;
    38 const double EPS = 1E-8, PI = acos(-1.0);
    39 
    40 #define DEBUG(...) fprintf(stderr, __VA_ARGS__)
    41 #define OK DEBUG("Passing [%s] in LINE %d...
    ", __FUNCTION__, __LINE__)
    42 
    43 const int MAXN = 10000 + 5;
    44 
    45 int cd[MAXN], het[MAXN];
    46 double left[MAXN], right[MAXN];
    47 LL f[MAXN];
    48 
    49 int main() {
    50   int n, h;
    51   LL x, y;
    52   scanf("%d%d%lld%lld", &n, &h, &x, &y);
    53   For(i, 1, n) {
    54     scanf("%d%d", &cd[i], &het[i]);
    55   }
    56   auto getR = [](double a, double b, double c) {
    57     return sqrt(2.0 * a * (b - c)) + a + b - c;
    58   };
    59   For(i, 1, n) {
    60     left[i] = -INF;
    61     Rep(j, i, 1) {
    62       chkmax(left[i], mymin((double)cd[j], cd[i] - 2.0 * getR(cd[i] - cd[j], h, het[j])));
    63     }
    64     right[i] = INF;
    65     For(j, i, n) {
    66       chkmin(right[i], mymax((double)cd[j], cd[i] + 2.0 * getR(cd[j] - cd[i], h, het[j])));
    67     }
    68   }
    69   memset(f, 0X3F, sizeof f);
    70   f[1] = x * (h - het[1]);
    71   For(i, 2, n) {
    72     REP(j, i, 1) {
    73       if (left[i] <= cd[j] && right[j] >= cd[i]) {
    74         chkmin(f[i], f[j] + x * (h - het[i]) + y * (cd[i] - cd[j]) * (cd[i] - cd[j]));
    75       }
    76     }
    77   }
    78   if (f[n] >= (LL)INF * INF) {
    79     puts("impossible");
    80     exit(0);
    81   }
    82   printf("%lld
    ", f[n]);
    83   return 0;
    84 }
    View Code

     C

    爆搜。先假定没有棋子,然后逐个按操作需要填,注意不能吃的时候封锁的棋子有两种可能。状态数实际上非常少,所以跑的很快。

    考场上谁爱写谁写。

      1 #include <bits/stdc++.h>
      2 
      3 #define IL __inline__ __attribute__((always_inline))
      4 
      5 #define For(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++ i)
      6 #define FOR(i, a, b) for (int i = (a), i##end = (b); i < i##end; ++ i)
      7 #define Rep(i, a, b) for (int i = (a), i##end = (b); i >= i##end; -- i)
      8 #define REP(i, a, b) for (int i = (a) - 1, i##end = (b); i >= i##end; -- i)
      9 
     10 typedef long long LL;
     11 
     12 template <class T>
     13 IL bool chkmax(T &a, const T &b) {
     14   return a < b ? ((a = b), 1) : 0;
     15 }
     16 
     17 template <class T>
     18 IL bool chkmin(T &a, const T &b) {
     19   return a > b ? ((a = b), 1) : 0;
     20 }
     21 
     22 template <class T>
     23 IL T mymax(const T &a, const T &b) {
     24   return a > b ? a : b;
     25 }
     26 
     27 template <class T>
     28 IL T mymin(const T &a, const T &b) {
     29   return a < b ? a : b;
     30 }
     31 
     32 template <class T>
     33 IL T myabs(const T &a) {
     34   return a > 0 ? a : -a;
     35 }
     36 
     37 const int INF = 0X3F3F3F3F;
     38 const double EPS = 1E-8, PI = acos(-1.0);
     39 
     40 #define DEBUG(...) fprintf(stderr, __VA_ARGS__)
     41 #define OK DEBUG("Passing [%s] in LINE %d...
    ", __FUNCTION__, __LINE__)
     42 
     43 const int MAXN = 30 + 5, MAXM = 100 + 5;
     44 const char F[5] = {0, 'w', 'W', 'b', 'B'};
     45 
     46 enum {
     47   MAX = 32
     48 };
     49 
     50 typedef int State[MAXN];
     51 
     52 State chess[MAXM]; // -1->unknown,0->empty,1->white,2->white_queen,3->black,4->black_queen
     53 int middle[MAXN][MAXN], origin[MAXN], n;
     54 bool type[MAXN]; // type:left->0,right->1
     55 std::vector<std::pair<int, int>> trans_w[MAXN], trans_b[MAXN], trans_q[MAXN]; // capture:white,black,queen
     56 
     57 struct Op {
     58   int type, start, end;
     59   std::vector<int> to;
     60 } oper[MAXM];
     61 
     62 IL void initTrans() {
     63   for (int i = 1; i <= MAX; i += 8) {
     64     type[i] = type[i + 1] = type[i + 2] = type[i + 3] = 1;
     65   }
     66   For(i, 1, MAX) {
     67     if (i > 8 && i % 4) {
     68       int x = type[i] ? i - 3 : i - 4;
     69       middle[i][i - 7] = x;
     70       trans_w[i].emplace_back(x, i - 7);
     71       trans_q[i].emplace_back(x, i - 7);
     72     } // right up capture
     73     if (i > 8 && (i - 1) % 4) {
     74       int x = type[i] ? i - 4 : i - 5;
     75       middle[i][i - 9] = x;
     76       trans_w[i].emplace_back(x, i - 9);
     77       trans_q[i].emplace_back(x, i - 9);
     78     } // left up capture
     79     if (i <= 24 && i % 4) {
     80       int x = type[i] ? i + 5 : i + 4;
     81       middle[i][i + 9] = x;
     82       trans_b[i].emplace_back(x, i + 9);
     83       trans_q[i].emplace_back(x, i + 9);
     84     } // right down capture
     85     if (i <= 24 && (i - 1) % 4) {
     86       int x = type[i] ? i + 4 : i + 3;
     87       middle[i][i + 7] = x;
     88       trans_b[i].emplace_back(x, i + 7);
     89       trans_q[i].emplace_back(x, i + 7);
     90     } // left down capture
     91   }
     92 }
     93 
     94 int DFS(int cur, bool p, std::vector<int> &wyp) { // -1:back to start,0:success,1:failure
     95   if (cur > n) {
     96     return 0;
     97   }
     98   memcpy(chess[cur], chess[cur - 1], sizeof chess[cur]);
     99   std::vector<int> waiting_l;
    100   if (p) { // black
    101     if (!~chess[cur][oper[cur].start]) {
    102       chess[0][oper[cur].start] = 3 + (oper[cur].start > 28);
    103       return -1;
    104     }
    105     if (chess[cur][oper[cur].start] <= 2) {
    106       return 1;
    107     }
    108     if (oper[cur].type) {
    109       int pos = oper[cur].start;
    110       for (auto &x : oper[cur].to) {
    111         if ((pos > 28 || x < pos) && chess[cur][pos] == 3) {
    112           chess[0][origin[pos]] = 4;
    113           return -1;
    114         }
    115         int wxh = middle[pos][x];
    116         if (!~chess[cur][wxh]) {
    117           chess[0][wxh] = 1;
    118           return -1;
    119         }
    120         if ((chess[cur][wxh] != 1 && chess[cur][wxh] != 2) || chess[cur][x] > 0) {
    121           return 1;
    122         }
    123         chess[cur][x] = chess[cur][pos];
    124         chess[cur][wxh] = chess[cur][pos] = 0;
    125         origin[x] = origin[pos];
    126         origin[wxh] = origin[pos] = 0;
    127         pos = x;
    128       }
    129       if (pos > 28 && chess[cur][pos] == 3) {
    130         chess[cur][pos] = 4;
    131       } else {
    132         for (auto &x : chess[cur][pos] == 3 ? trans_b[pos] : trans_q[pos]) {
    133           if (chess[cur][x.first] == 1 || chess[cur][x.first] == 2) {
    134             if (!chess[cur][x.second]) {
    135               return 1;
    136             } else if (!~chess[cur][x.second]) {
    137               waiting_l.push_back(x.second);
    138             }
    139           }
    140         }
    141       }
    142     } else {
    143       For(i, 1, MAX) {
    144         if (chess[cur][i] == 3 || chess[cur][i] == 4) {
    145           for (auto &x : chess[cur][i] == 3 ? trans_b[i] : trans_q[i]) {
    146             if (chess[cur][x.first] == 1 || chess[cur][x.first] == 2) {
    147               if (!chess[cur][x.second]) {
    148                 return 1;
    149               } else if (!~chess[cur][x.second]) {
    150                 waiting_l.push_back(x.second);
    151               }
    152             }
    153           }
    154         }
    155       }
    156       int s = oper[cur].start, e = oper[cur].end;
    157       if (chess[cur][e] > 0) {
    158         return 1;
    159       }
    160       if (chess[cur][s] == 3 && s > e) {
    161         chess[0][origin[s]] = 4;
    162         return -1;
    163       }
    164       if (e > 28) {
    165         chess[cur][s] = 4;
    166       }
    167       chess[cur][e] = chess[cur][s];
    168       chess[cur][s] = 0;
    169       origin[e] = origin[s];
    170       origin[s] = 0;
    171     }
    172   } else { // white
    173     if (!~chess[cur][oper[cur].start]) {
    174       chess[0][oper[cur].start] = 1 + (oper[cur].start <= 4);
    175       return -1;
    176     }
    177     if (!chess[cur][oper[cur].start] || chess[cur][oper[cur].start] >= 3) {
    178       return 1;
    179     }
    180     if (oper[cur].type) {
    181       int pos = oper[cur].start;
    182       for (auto &x : oper[cur].to) {
    183         if ((pos <= 4 || x > pos) && chess[cur][pos] == 1) {
    184           chess[0][origin[pos]] = 2;
    185           return -1;
    186         }
    187         int wxh = middle[pos][x];
    188         if (!~chess[cur][wxh]) {
    189           chess[0][wxh] = 3;
    190           return -1;
    191         }
    192         if ((chess[cur][wxh] != 3 && chess[cur][wxh] != 4) || chess[cur][x] > 0) {
    193           return 1;
    194         }
    195         chess[cur][x] = chess[cur][pos];
    196         chess[cur][wxh] = chess[cur][pos] = 0;
    197         origin[x] = origin[pos];
    198         origin[wxh] = origin[pos] = 0;
    199         pos = x;
    200       }
    201       if (pos <= 4 && chess[cur][pos] == 1) {
    202         chess[cur][pos] = 2;
    203       } else {
    204         for (auto &x : chess[cur][pos] == 1 ? trans_w[pos] : trans_q[pos]) {
    205           if (chess[cur][x.first] == 3 || chess[cur][x.first] == 4) {
    206             if (!chess[cur][x.second]) {
    207               return 1;
    208             } else if (!~chess[cur][x.second]) {
    209               waiting_l.push_back(x.second);
    210             }
    211           }
    212         }
    213       }
    214     } else {
    215       For(i, 1, MAX) {
    216         if (chess[cur][i] == 1 || chess[cur][i] == 2) {
    217           for (auto &x : chess[cur][i] == 1 ? trans_w[i] : trans_q[i]) {
    218             if (chess[cur][x.first] == 3 || chess[cur][x.first] == 4) {
    219               if (!chess[cur][x.second]) {
    220                 return 1;
    221               } else if (!~chess[cur][x.second]) {
    222                 waiting_l.push_back(x.second);
    223               }
    224             }
    225           }
    226         }
    227       }
    228       int s = oper[cur].start, e = oper[cur].end;
    229       if (chess[cur][e] > 0) {
    230         return 1;
    231       }
    232       if (chess[cur][s] == 1 && s < e) {
    233         chess[0][origin[s]] = 2;
    234         return -1;
    235       }
    236       if (e <= 4) {
    237         chess[cur][s] = 2;
    238       }
    239       chess[cur][e] = chess[cur][s];
    240       chess[cur][s] = 0;
    241       origin[e] = origin[s];
    242       origin[s] = 0;
    243     }
    244   }
    245   if (waiting_l.empty()) {
    246     return DFS(cur + 1, !p, wyp);
    247   } else {
    248     wyp = waiting_l;
    249     return -1;
    250   }
    251 }
    252 
    253 bool getChess(bool p, const std::vector<int> &dxd) {
    254   int cur[MAXN];
    255   memcpy(cur, chess[0], sizeof cur);
    256   FOR(S, 0, 1 << dxd.size()) {
    257     std::vector<int> tp;
    258     FOR(i, 0, dxd.size()) {
    259       chess[0][dxd[i]] = (S & (1 << i)) ? 1 : 3;
    260       if ((chess[0][dxd[i]] == 1 && dxd[i] <= 4) || (chess[0][dxd[i]] == 3 && dxd[i] > 28)) {
    261         ++ chess[0][dxd[i]];
    262       }
    263     }
    264     while (1) {
    265       memset(origin, 0, sizeof origin);
    266       For(i, 1, MAX) {
    267         if (chess[0][i]) {
    268           origin[i] = i;
    269         }
    270       }
    271       int val = DFS(1, p, tp);
    272       if (!val) {
    273         return 1;
    274       }
    275       if (val == 1) {
    276         break;
    277       }
    278       if (!tp.empty()) {
    279         if (getChess(p, tp)) {
    280           return 1;
    281         }
    282         break;
    283       }
    284     }
    285   }
    286   memcpy(chess[0], cur, sizeof chess[0]);
    287   return 0;
    288 }
    289 
    290 int main() {
    291   initTrans();
    292   static char opt[MAXM];
    293   scanf("%s%d", opt, &n);
    294   bool s = opt[0] == 'B';
    295   For(i, 1, n) {
    296     scanf("%s", opt);
    297     int len = strlen(opt), num = 0;
    298     bool tp = 0;
    299     FOR(j, 0, len) {
    300       if (isdigit(opt[j])) {
    301         num = num * 10 + opt[j] - '0';
    302       } else if (opt[j] == 'x') {
    303         tp = 1;
    304         if (!oper[i].start) {
    305           oper[i].start = num;
    306         } else {
    307           oper[i].to.push_back(num);
    308         }
    309         num = 0;
    310       } else {
    311         oper[i].start = num;
    312         num = 0;
    313       }
    314     }
    315     if (tp) {
    316       oper[i].to.push_back(num);
    317     } else {
    318       oper[i].end = num;
    319     }
    320     oper[i].type = tp;
    321   }
    322   memset(chess[0], -1, sizeof chess[0]);
    323   getChess(s, std::vector<int>());
    324   For(i, 1, 8) {
    325     if (i & 1) {
    326       For(j, (i - 1) * 4 + 1, i * 4) {
    327         putchar('-');
    328         putchar(chess[0][j] <= 0 ? '.' : F[chess[0][j]]);
    329       }
    330       putchar(' ');
    331       For(j, (i - 1) * 4 + 1, i * 4) {
    332         putchar('-');
    333         putchar(chess[n][j] <= 0 ? '.' : F[chess[n][j]]);
    334       }
    335       putchar('
    ');
    336     } else {
    337       For(j, (i - 1) * 4 + 1, i * 4) {
    338         putchar(chess[0][j] <= 0 ? '.' : F[chess[0][j]]);
    339         putchar('-');
    340       }
    341       putchar(' ');
    342       For(j, (i - 1) * 4 + 1, i * 4) {
    343         putchar(chess[n][j] <= 0 ? '.' : F[chess[n][j]]);
    344         putchar('-');
    345       }
    346       putchar('
    ');
    347     }
    348   }
    349   return 0;
    350 }
    View Code

     D

    把每一个基因类抽出来,可以发现是一个括号序列,扫一遍,线段树维护前缀和最小值即可。

    (实际上对每一个类单独考虑合法位置之后差分即可做到线性,我数据结构学傻了.jpg

      1 #include <bits/stdc++.h>
      2 
      3 #define IL __inline__ __attribute__((always_inline))
      4 
      5 #define For(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++ i)
      6 #define FOR(i, a, b) for (int i = (a), i##end = (b); i < i##end; ++ i)
      7 #define Rep(i, a, b) for (int i = (a), i##end = (b); i >= i##end; -- i)
      8 #define REP(i, a, b) for (int i = (a) - 1, i##end = (b); i >= i##end; -- i)
      9 
     10 typedef long long LL;
     11 
     12 template <class T>
     13 IL bool chkmax(T &a, const T &b) {
     14   return a < b ? ((a = b), 1) : 0;
     15 }
     16 
     17 template <class T>
     18 IL bool chkmin(T &a, const T &b) {
     19   return a > b ? ((a = b), 1) : 0;
     20 }
     21 
     22 template <class T>
     23 IL T mymax(const T &a, const T &b) {
     24   return a > b ? a : b;
     25 }
     26 
     27 template <class T>
     28 IL T mymin(const T &a, const T &b) {
     29   return a < b ? a : b;
     30 }
     31 
     32 template <class T>
     33 IL T myabs(const T &a) {
     34   return a > 0 ? a : -a;
     35 }
     36 
     37 const int INF = 0X3F3F3F3F;
     38 const double EPS = 1E-8, PI = acos(-1.0);
     39 
     40 #define DEBUG(...) fprintf(stderr, __VA_ARGS__)
     41 #define OK DEBUG("Passing [%s] in LINE %d...
    ", __FUNCTION__, __LINE__)
     42 
     43 const int MAXN = 1000000 + 5;
     44 
     45 struct SegmentTree {
     46   int *min, *tag;
     47 
     48 #define lc (o << 1)
     49 #define rc (o << 1 | 1)
     50   void pushUp(int o) {
     51     min[o] = mymin(min[lc], min[rc]);
     52   }
     53 
     54   void pushDown(int o) {
     55     if (tag[o]) {
     56       min[lc] += tag[o], tag[lc] += tag[o];
     57       min[rc] += tag[o], tag[rc] += tag[o];
     58       tag[o] = 0;
     59     }
     60   }
     61 
     62   void build(int o, int l, int r) {
     63     min[o] = INF, tag[o] = 0;
     64     if (l == r) {
     65       return;
     66     }
     67     int mid = (l + r) >> 1;
     68     build(lc, l, mid);
     69     build(rc, mid + 1, r);
     70   }
     71 
     72   void modify(int o, int l, int r, int p, int x) {
     73     if (l == r) {
     74       min[o] = x;
     75       return;
     76     }
     77     int mid = (l + r) >> 1;
     78     pushDown(o);
     79     if (p <= mid) {
     80       modify(lc, l, mid, p, x);
     81     } else {
     82       modify(rc, mid + 1, r, p, x);
     83     }
     84     pushUp(o);
     85   }
     86 
     87   void modify(int o, int l, int r, int a, int b, int x) {
     88     if (l >= a && r <= b) {
     89       min[o] += x, tag[o] += x;
     90       return;
     91     }
     92     int mid = (l + r) >> 1;
     93     pushDown(o);
     94     if (a <= mid) {
     95       modify(lc, l, mid, a, b, x);
     96     }
     97     if (b > mid) {
     98       modify(rc, mid + 1, r, a, b, x);
     99     }
    100     pushUp(o);
    101   }
    102 
    103   int query(int o, int l, int r, int a, int b) {
    104     if (l >= a && r <= b) {
    105       return min[o];
    106     }
    107     int mid = (l + r) >> 1, answer = INF;
    108     pushDown(o);
    109     if (a <= mid) {
    110       chkmin(answer, query(lc, l, mid, a, b));
    111     }
    112     if (b > mid) {
    113       chkmin(answer, query(rc, mid + 1, r, a, b));
    114     }
    115     pushUp(o);
    116     return answer;
    117   }
    118 } seg[MAXN];
    119 
    120 std::pair<int, int> gene[MAXN];
    121 std::vector<int> wxh;
    122 int pos[MAXN], sum[MAXN], cnt[MAXN], cur[MAXN];
    123 
    124 int main() {
    125   int n;
    126   scanf("%d", &n);
    127   For(i, 1, n) {
    128     static char opt[15];
    129     scanf("%s", opt);
    130     int len = strlen(opt);
    131     gene[i].second = opt[0] == 's' ? 1 : -1;
    132     FOR(j, 1, len) {
    133       gene[i].first = gene[i].first * 10 + opt[j] - '0';
    134     }
    135     pos[i] = ++ cnt[gene[i].first];
    136     sum[gene[i].first] += gene[i].second;
    137   }
    138   For(i, 1, n) {
    139     if (!sum[gene[i].first]) {
    140       int x = gene[i].first;
    141       if (!seg[x].min) {
    142         wxh.push_back(x);
    143         seg[x].min = new int[cnt[x] * 8 + 5], seg[x].tag = new int[cnt[x] * 8 + 5];
    144         seg[x].build(1, 1, cnt[x] * 2);
    145       }
    146       seg[x].modify(1, 1, cnt[x] * 2, pos[i], cur[x] += gene[i].second);
    147     }
    148   }
    149   int answer = 0, result = 1;
    150   for (auto &x : wxh) {
    151     answer += !seg[x].min[1];
    152   }
    153   int cur = answer;
    154   FOR(i, 1, n) {
    155     if (!sum[gene[i].first]) {
    156       int x = gene[i].first;
    157       cur -= !seg[x].query(1, 1, cnt[x] * 2, pos[i], pos[i] + cnt[x] - 1);
    158       seg[x].modify(1, 1, cnt[x] * 2, pos[i] + 1, pos[i] + cnt[x] - 1, -gene[i].second);
    159       seg[x].modify(1, 1, cnt[x] * 2, pos[i] + cnt[x], 0);
    160       cur += !seg[x].query(1, 1, cnt[x] * 2, pos[i] + 1, pos[i] + cnt[x]);
    161       if (chkmax(answer, cur)) {
    162         result = i + 1;
    163       }
    164     }
    165   }
    166   printf("%d %d
    ", result, answer);
    167   return 0;
    168 }
    View Code

     E

    可以发现一个边双里一定没有断头路,所以把边双缩起来之后在进一棵在原图上是树的子树时放标志即可,注意如果联通块是树需要特判(此时在所有叶子处放标志)。

      1 #include <bits/stdc++.h>
      2 
      3 #define IL __inline__ __attribute__((always_inline))
      4 
      5 #define For(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++ i)
      6 #define FOR(i, a, b) for (int i = (a), i##end = (b); i < i##end; ++ i)
      7 #define Rep(i, a, b) for (int i = (a), i##end = (b); i >= i##end; -- i)
      8 #define REP(i, a, b) for (int i = (a) - 1, i##end = (b); i >= i##end; -- i)
      9 
     10 typedef long long LL;
     11 
     12 template <class T>
     13 IL bool chkmax(T &a, const T &b) {
     14   return a < b ? ((a = b), 1) : 0;
     15 }
     16 
     17 template <class T>
     18 IL bool chkmin(T &a, const T &b) {
     19   return a > b ? ((a = b), 1) : 0;
     20 }
     21 
     22 template <class T>
     23 IL T mymax(const T &a, const T &b) {
     24   return a > b ? a : b;
     25 }
     26 
     27 template <class T>
     28 IL T mymin(const T &a, const T &b) {
     29   return a < b ? a : b;
     30 }
     31 
     32 template <class T>
     33 IL T myabs(const T &a) {
     34   return a > 0 ? a : -a;
     35 }
     36 
     37 const int INF = 0X3F3F3F3F;
     38 const double EPS = 1E-8, PI = acos(-1.0);
     39 
     40 #define DEBUG(...) fprintf(stderr, __VA_ARGS__)
     41 #define OK DEBUG("Passing [%s] in LINE %d...
    ", __FUNCTION__, __LINE__)
     42 
     43 const int MAXN = 500000 + 5;
     44 
     45 struct Input {
     46   char buf[1 << 24], *st, *ed;
     47   
     48   Input() {
     49 #ifndef ONLINE_JUDGE
     50     freopen("LOJ6581.in", "r", stdin);
     51 #endif
     52   }
     53   
     54   char get() {
     55     if (st == ed) {
     56       ed = buf + fread(st = buf, 1, 1 << 24, stdin);
     57     }
     58     return *st ++;
     59   }
     60   
     61   friend Input &operator>>(Input &io, int &x) {
     62     x = 0;
     63     static char ch;
     64     while (!isdigit(ch = io.get()));
     65     do {
     66       x = x * 10 + ch - '0';
     67     } while (isdigit(ch = io.get()));
     68     return io;
     69   }
     70 } cin;
     71 
     72 int size[MAXN], bel[MAXN], deg[MAXN], bc[MAXN], fa[MAXN], bcc_cnt, con_cnt;
     73 bool ok[MAXN], is_o[MAXN];
     74 std::vector<int> adj[MAXN], pt[MAXN];
     75 std::vector<std::pair<int, int>> dd[MAXN], answer;
     76 
     77 IL void addEdge(int u, int v) {
     78   ++ deg[bel[v]];
     79   adj[bel[u]].push_back(bel[v]);
     80   dd[bel[u]].push_back({u, v});
     81 }
     82 
     83 void DFS1(int u) {
     84   pt[con_cnt].push_back(u);
     85   bc[u] = con_cnt;
     86   FOR(i, 0, adj[u].size()) {
     87     int v = adj[u][i];
     88     if (v != fa[u]) {
     89       fa[v] = u;
     90       DFS1(v);
     91     }
     92   }
     93 }
     94 
     95 bool DFS2(int u) {
     96   is_o[u] = size[u] != 1;
     97   FOR(i, 0, adj[u].size()) {
     98     int v = adj[u][i];
     99     if (v != fa[u]) {
    100       fa[v] = u;
    101       is_o[u] |= DFS2(v);
    102     }
    103   }
    104   return is_o[u];
    105 }
    106 
    107 void DFS3(int u) {
    108   FOR(i, 0, adj[u].size()) {
    109     int v = adj[u][i];
    110     if (v != fa[u]) {
    111       if (is_o[v]) {
    112         DFS3(v);
    113       } else {
    114         answer.push_back(dd[u][i]);
    115       }
    116     }
    117   }
    118 }
    119 
    120 struct Edge {
    121   int u, v;
    122 } edge[MAXN];
    123 
    124 struct Graph {
    125   int hed[MAXN], nxt[MAXN * 2], to[MAXN * 2], bridge[MAXN * 2], fa[MAXN], dfn[MAXN], low[MAXN], cnt, num;
    126   bool vis[MAXN];
    127 
    128   Graph() {
    129     cnt = 1;
    130   }
    131 
    132   void addEdge(int u, int v) {
    133     ++ cnt;
    134     to[cnt] = v;
    135     nxt[cnt] = hed[u];
    136     hed[u] = cnt;
    137   }
    138 
    139   void DFS1(int u) {
    140     low[u] = dfn[u] = ++ num;
    141     for (int e = hed[u]; e; e = nxt[e]) {
    142       int v = to[e];
    143       if (!dfn[v]) {
    144         fa[v] = u;
    145         DFS1(v);
    146         chkmin(low[u], low[v]);
    147         if (low[v] >= dfn[u]) {
    148           bridge[e] = bridge[e ^ 1] = 1;
    149         }
    150       } else if (v != fa[u]) {
    151         chkmin(low[u], dfn[v]);
    152       }
    153     }
    154   }
    155 
    156   void DFS2(int u, int k) {
    157     ++ size[k];
    158     bel[u] = k;
    159     vis[u] = 1;
    160     for (int e = hed[u]; e; e = nxt[e]) {
    161       int v = to[e];
    162       if (!bridge[e] && !vis[v]) {
    163         DFS2(v, k);
    164       }
    165     }
    166   }
    167 } G;
    168 
    169 int main() {
    170   int n, m;
    171   cin >> n >> m;
    172   For(i, 1, m) {
    173     cin >> edge[i].u >> edge[i].v;
    174     G.addEdge(edge[i].u, edge[i].v);
    175     G.addEdge(edge[i].v, edge[i].u);
    176   }
    177   For(i, 1, n) {
    178     if (!G.dfn[i]) {
    179       G.DFS1(i);
    180     }
    181   }
    182   For(i, 1, n) {
    183     if (!G.vis[i]) {
    184       G.DFS2(i, ++ bcc_cnt);
    185     }
    186   }
    187   For(i, 1, m) {
    188     if (bel[edge[i].u] != bel[edge[i].v]) {
    189       addEdge(edge[i].u, edge[i].v);
    190       addEdge(edge[i].v, edge[i].u);
    191     }
    192   }
    193   For(i, 1, bcc_cnt) {
    194     if (!bc[i]) {
    195       ++ con_cnt;
    196       DFS1(i);
    197     }
    198   }
    199   For(i, 1, bcc_cnt) {
    200     ok[bc[i]] |= size[i] != 1;
    201   }
    202   For(i, 1, con_cnt) {
    203     if (ok[i]) {
    204       for (auto &x : pt[i]) {
    205         if (size[x] > 1) {
    206           fa[x] = 0;
    207           DFS2(x);
    208           DFS3(x);
    209           break;
    210         }
    211       }
    212     } else {
    213       for (auto &x : pt[i]) {
    214         if (deg[x] == 1) {
    215           answer.push_back(dd[x].front());
    216         }
    217       }
    218     }
    219   }
    220   std::sort(answer.begin(), answer.end());
    221   printf("%u
    ", answer.size());
    222   for (auto &x : answer) {
    223     printf("%d %d
    ", x.first, x.second);
    224   }
    225   return 0;
    226 }
    View Code

     F

    先把线段按从下往上的顺序拓扑排序,这个可以扫描线。

    然后问题变成了这样:

    初始有一个序列$V$,形如一段$infty$接一段$0$再接一段$infty$。

    有$n$次操作,每次操作给定区间$[l,r]$,然后对于$iin[l,r]$,将$V_i$变为$min(V_l,1+min_{j=l}^iV_j)$或$min(V_r,1+min_{j=i}^rV_j)$。

    注意到这个序列一定是单谷的,所以可以用线段树维护。

      1 #include <bits/stdc++.h>
      2 
      3 #define IL __inline__ __attribute__((always_inline))
      4 
      5 #define For(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++ i)
      6 #define FOR(i, a, b) for (int i = (a), i##end = (b); i < i##end; ++ i)
      7 #define Rep(i, a, b) for (int i = (a), i##end = (b); i >= i##end; -- i)
      8 #define REP(i, a, b) for (int i = (a) - 1, i##end = (b); i >= i##end; -- i)
      9 
     10 typedef long long LL;
     11 
     12 template <class T>
     13 IL bool chkmax(T &a, const T &b) {
     14   return a < b ? ((a = b), 1) : 0;
     15 }
     16 
     17 template <class T>
     18 IL bool chkmin(T &a, const T &b) {
     19   return a > b ? ((a = b), 1) : 0;
     20 }
     21 
     22 template <class T>
     23 IL T mymax(const T &a, const T &b) {
     24   return a > b ? a : b;
     25 }
     26 
     27 template <class T>
     28 IL T mymin(const T &a, const T &b) {
     29   return a < b ? a : b;
     30 }
     31 
     32 template <class T>
     33 IL T myabs(const T &a) {
     34   return a > 0 ? a : -a;
     35 }
     36 
     37 const int INF = 0X3F3F3F3F;
     38 const double EPS = 1E-8, PI = acos(-1.0);
     39 
     40 #define DEBUG(...) fprintf(stderr, __VA_ARGS__)
     41 #define OK DEBUG("Passing [%s] in LINE %d...
    ", __FUNCTION__, __LINE__)
     42 
     43 const int MAXN = 1000000 + 5;
     44 
     45 struct Input {
     46   char buf[1 << 25], *s;
     47 
     48   Input() {
     49     fread(s = buf, 1, 1 << 25, stdin);
     50   }
     51 
     52   friend Input &operator>>(Input &io, int &x) {
     53     x = 0;
     54     while (!isdigit(*io.s)) {
     55       ++ io.s;
     56     }
     57     while (isdigit(*io.s)) {
     58       x = x * 10 + *io.s ++ - '0';
     59     }
     60     return io;
     61   }
     62 } cin;
     63 
     64 struct Point {
     65   int x, y;
     66 
     67   Point() {}
     68   Point(int _x, int _y) : x(_x), y(_y) {}
     69 };
     70 
     71 std::pair<Point, Point> seg[MAXN], cc[MAXN];
     72 std::vector<int> bg[MAXN * 2], ed[MAXN * 2];
     73 int ts[MAXN * 2], L, R, cur;
     74 
     75 struct Comp {
     76   double calc_c(int c, const std::pair<Point, Point> &s) {
     77     return (double)(c - s.first.x) / (s.first.x - s.second.x) * (s.first.y - s.second.y) + s.first.y;
     78   }
     79 
     80   bool operator()(int a, int b) {
     81     return calc_c(cur, cc[a]) < calc_c(cur, cc[b]);
     82   }
     83 };
     84 
     85 std::set<int, Comp> s;
     86 std::vector<int> adj[MAXN];
     87 int deg[MAXN], topo[MAXN];
     88 
     89 struct SegmentTree {
     90   int min[MAXN * 8], pos[MAXN * 8], tag1[MAXN * 8], tag2[MAXN * 8];
     91 
     92   SegmentTree() {
     93     memset(tag2, -1, sizeof tag2);
     94   }
     95 
     96 #define lc (o << 1)
     97 #define rc (o << 1 | 1)
     98   void pushUp(int o) {
     99     min[o] = mymin(min[lc], min[rc]);
    100     if (min[lc] <= min[rc]) {
    101       pos[o] = pos[lc];
    102     } else {
    103       pos[o] = pos[rc];
    104     }
    105   }
    106 
    107   void pushDown(int o) {
    108     if (~tag2[o]) {
    109       min[lc] = tag2[o], tag1[lc] = 0, tag2[lc] = tag2[o];
    110       min[rc] = tag2[o], tag1[rc] = 0, tag2[rc] = tag2[o];
    111       tag2[o] = -1;
    112     }
    113     if (tag1[o]) {
    114       min[lc] += tag1[o], tag1[lc] += tag1[o];
    115       min[rc] += tag1[o], tag1[rc] += tag1[o];
    116       tag1[o] = 0;
    117     }
    118   }
    119 
    120   void build(int o, int l, int r) {
    121     if (l == r) {
    122       min[o] = l >= L && l <= R ? 0 : INF;
    123       pos[o] = l;
    124       return;
    125     }
    126     int mid = (l + r) >> 1;
    127     build(lc, l, mid);
    128     build(rc, mid + 1, r);
    129     pushUp(o);
    130   }
    131 
    132   void add(int o, int l, int r, int a, int b, int x) {
    133     if (a > b) {
    134       return;
    135     }
    136     if (l >= a && r <= b) {
    137       min[o] += x, tag1[o] += x;
    138       return;
    139     }
    140     int mid = (l + r) >> 1;
    141     pushDown(o);
    142     if (a <= mid) {
    143       add(lc, l, mid, a, b, x);
    144     }
    145     if (b > mid) {
    146       add(rc, mid + 1, r, a, b, x);
    147     }
    148     pushUp(o);
    149   }
    150 
    151   void set(int o, int l, int r, int a, int b, int x) {
    152     if (a > b) {
    153       return;
    154     }
    155     if (l >= a && r <= b) {
    156       min[o] = x, tag1[o] = 0, tag2[o] = x;
    157       return;
    158     }
    159     int mid = (l + r) >> 1;
    160     pushDown(o);
    161     if (a <= mid) {
    162       set(lc, l, mid, a, b, x);
    163     }
    164     if (b > mid) {
    165       set(rc, mid + 1, r, a, b, x);
    166     }
    167     pushUp(o);
    168   }
    169 
    170   std::pair<int, int> query_v(int o, int l, int r, int a, int b) {
    171     if (l >= a && r <= b) {
    172       return {min[o], pos[o]};
    173     }
    174     int mid = (l + r) >> 1;
    175     std::pair<int, int> answer(INF, INF);
    176     pushDown(o);
    177     if (a <= mid) {
    178       chkmin(answer, query_v(lc, l, mid, a, b));
    179     }
    180     if (b > mid) {
    181       chkmin(answer, query_v(rc, mid + 1, r, a, b));
    182     }
    183     return answer;
    184   }
    185 
    186   int query1(int o, int l, int r, int a, int b, int x) {
    187     if (l >= a && r <= b) {
    188       if (min[o] < x) {
    189         while (l != r) {
    190           int mid = (l + r) >> 1;
    191           pushDown(o);
    192           if (min[lc] < x) {
    193             o = lc, r = mid;
    194           } else {
    195             o = rc, l = mid + 1;
    196           }
    197         }
    198         return l;
    199       } else {
    200         return INF;
    201       }
    202     }
    203     int mid = (l + r) >> 1;
    204     pushDown(o);
    205     if (a <= mid) {
    206       int result = query1(lc, l, mid, a, b, x);
    207       if (result < INF) {
    208         return result;
    209       }
    210     }
    211     if (b > mid) {
    212       int result = query1(rc, mid + 1, r, a, b, x);
    213       if (result < INF) {
    214         return result;
    215       }
    216     }
    217     return INF;
    218   }
    219 
    220   int query2(int o, int l, int r, int a, int b, int x) {
    221     if (l >= a && r <= b) {
    222       if (min[o] < x) {
    223         while (l != r) {
    224           int mid = (l + r) >> 1;
    225           pushDown(o);
    226           if (min[rc] < x) {
    227             o = rc, l = mid + 1;
    228           } else {
    229             o = lc, r = mid;
    230           }
    231         }
    232         return l;
    233       } else {
    234         return -INF;
    235       }
    236     }
    237     int mid = (l + r) >> 1;
    238     pushDown(o);
    239     if (b > mid) {
    240       int result = query2(rc, mid + 1, r, a, b, x);
    241       if (result > -INF) {
    242         return result;
    243       }
    244     }
    245     if (a <= mid) {
    246       int result = query2(lc, l, mid, a, b, x);
    247       if (result > -INF) {
    248         return result;
    249       }
    250     }
    251     return -INF;
    252   }
    253 } segt;
    254 
    255 int main() {
    256   int n;
    257   cin >> L >> R >> n;
    258   int cnt = 0;
    259   ts[++ cnt] = L, ts[++ cnt] = R;
    260   For(i, 1, n) {
    261     cin >> seg[i].first.x >> seg[i].first.y >> seg[i].second.x >> seg[i].second.y;
    262     cc[i] = seg[i];
    263     ts[++ cnt] = seg[i].first.x, ts[++ cnt] = seg[i].second.x;
    264   }
    265   std::sort(ts + 1, ts + cnt + 1);
    266   cnt = std::unique(ts + 1, ts + cnt + 1) - 1 - ts;
    267   L = std::lower_bound(ts + 1, ts + cnt + 1, L) - ts, R = std::lower_bound(ts + 1, ts + cnt + 1, R) - ts;
    268   L <<= 1, R <<= 1;
    269   For(i, 1, n) {
    270     seg[i].first.x = std::lower_bound(ts + 1, ts + cnt + 1, seg[i].first.x) - ts;
    271     seg[i].second.x = std::lower_bound(ts + 1, ts + cnt + 1, seg[i].second.x) - ts;
    272     int p = seg[i].first.x, q = seg[i].second.x;
    273     if (p < q) {
    274       bg[p].push_back(i), ed[q].push_back(i);
    275     } else {
    276       bg[q].push_back(i), ed[p].push_back(i);
    277       std::swap(seg[i].first, seg[i].second);
    278     }
    279     seg[i].first.x <<= 1, seg[i].second.x <<= 1;
    280   }
    281   For(i, 1, cnt) {
    282     cur = ts[i];
    283     for (auto &x : bg[i]) {
    284       auto it = s.insert(x).first;
    285       if (*it != *s.begin()) {
    286         auto p = it;
    287         -- p;
    288         adj[*p].push_back(x);
    289         ++ deg[x];
    290       }
    291       if (*it != *s.rbegin()) {
    292         auto p = it;
    293         ++ p;
    294         adj[x].push_back(*p);
    295         ++ deg[*p];
    296       }
    297     }
    298     for (auto &x : ed[i]) {
    299       s.erase(x);
    300     }
    301   }
    302   cnt <<= 1;
    303   int l = 1, r = 0;
    304   For(i, 1, n) {
    305     if (!deg[i]) {
    306       topo[++ r] = i;
    307     }
    308   }
    309   while (l <= r) {
    310     int u = topo[l ++];
    311     for (auto &x : adj[u]) {
    312       if (!(-- deg[x])) {
    313         topo[++ r] = x;
    314       }
    315     }
    316   }
    317   segt.build(1, 1, cnt);
    318   For(i, 1, n) {
    319     int x = topo[i], l = seg[x].first.x, r = seg[x].second.x;
    320     if (seg[x].first.y < seg[x].second.y) {
    321       int val = segt.query_v(1, 1, cnt, l, l).first;
    322       std::pair<int, int> min = segt.query_v(1, 1, cnt, l, r);
    323       if (min.first == val) {
    324         segt.set(1, 1, cnt, l, r, val);
    325       } else {
    326         segt.set(1, 1, cnt, min.second, r, min.first);
    327         int p = segt.query1(1, 1, cnt, l, r, val);
    328         segt.add(1, 1, cnt, p, r, 1);
    329       }
    330     } else {
    331       int val = segt.query_v(1, 1, cnt, r, r).first;
    332       std::pair<int, int> min = segt.query_v(1, 1, cnt, l, r);
    333       if (min.first == val) {
    334         segt.set(1, 1, cnt, l, r, val);
    335       } else {
    336         segt.set(1, 1, cnt, l, min.second, min.first);
    337         int p = segt.query2(1, 1, cnt, l, r, val);
    338         segt.add(1, 1, cnt, l, p, 1);
    339       }
    340     }
    341   }
    342   printf("%d
    ", segt.query_v(1, 1, cnt, L, R).first);
    343   return 0;
    344 }
    View Code

     G

    把模式串倒过来建AC自动机,相当于文本串是一个Trie,和是一个单串并没有本质区别,直接跑匹配即可。

      1 #include <bits/stdc++.h>
      2 
      3 #define IL __inline__ __attribute__((always_inline))
      4 
      5 #define For(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++ i)
      6 #define FOR(i, a, b) for (int i = (a), i##end = (b); i < i##end; ++ i)
      7 #define Rep(i, a, b) for (int i = (a), i##end = (b); i >= i##end; -- i)
      8 #define REP(i, a, b) for (int i = (a) - 1, i##end = (b); i >= i##end; -- i)
      9 
     10 typedef long long LL;
     11 
     12 template <class T>
     13 IL bool chkmax(T &a, const T &b) {
     14   return a < b ? ((a = b), 1) : 0;
     15 }
     16 
     17 template <class T>
     18 IL bool chkmin(T &a, const T &b) {
     19   return a > b ? ((a = b), 1) : 0;
     20 }
     21 
     22 template <class T>
     23 IL T mymax(const T &a, const T &b) {
     24   return a > b ? a : b;
     25 }
     26 
     27 template <class T>
     28 IL T mymin(const T &a, const T &b) {
     29   return a < b ? a : b;
     30 }
     31 
     32 template <class T>
     33 IL T myabs(const T &a) {
     34   return a > 0 ? a : -a;
     35 }
     36 
     37 const int INF = 0X3F3F3F3F;
     38 const double EPS = 1E-8, PI = acos(-1.0);
     39 
     40 #define DEBUG(...) fprintf(stderr, __VA_ARGS__)
     41 #define OK DEBUG("Passing [%s] in LINE %d...
    ", __FUNCTION__, __LINE__)
     42 
     43 const int MAXN = 1000000 + 5;
     44 
     45 std::vector<int> adj[MAXN];
     46 int answer[MAXN], val[MAXN], n;
     47 char str[MAXN];
     48 
     49 struct AhoCorasickAutomaton {
     50   int ch[MAXN][26], fail[MAXN], num[MAXN], cnt;
     51   std::vector<int> id[MAXN], t[MAXN];
     52 
     53   AhoCorasickAutomaton() {
     54     memset(ch, -1, sizeof (ch));
     55   }
     56 
     57   void insert(int len, int p) {
     58     int cur = 0;
     59     For(i, 1, len) {
     60       if (!~ch[cur][str[i] - 'A']) {
     61         ch[cur][str[i] - 'A'] = ++ cnt;
     62       }
     63       cur = ch[cur][str[i] - 'A'];
     64     }
     65     id[cur].push_back(p);
     66   }
     67 
     68   void build() {
     69     static int queue[MAXN];
     70     int l = 1, r = 0;
     71     queue[++ r] = 0;
     72     while (l <= r) {
     73       int u = queue[l ++];
     74       FOR(i, 0, 26) {
     75         if (!~ch[u][i]) {
     76           ch[u][i] = u ? ch[fail[u]][i] : 0;
     77           continue;
     78         }
     79         fail[ch[u][i]] = u ? ch[fail[u]][i] : 0;
     80         t[fail[ch[u][i]]].push_back(ch[u][i]);
     81         queue[++ r] = ch[u][i];
     82       }
     83     }
     84   }
     85 
     86   void DFS(int u) {
     87     for (auto &x : t[u]) {
     88       DFS(x);
     89       num[u] += num[x];
     90     }
     91     for (auto &x : id[u]) {
     92       answer[x] = num[u];
     93     }
     94   }
     95 } ac;
     96 
     97 void DFS(int u, int cur) {
     98   cur = ac.ch[cur][val[u]];
     99   ++ ac.num[cur];
    100   for (auto &x : adj[u]) {
    101     DFS(x, cur);
    102   }
    103 }
    104 
    105 int main() {
    106   int k;
    107   scanf("%d%d", &n, &k);
    108   For(i, 1, n) {
    109     int u;
    110     scanf("%s%d", str, &u);
    111     val[i] = str[0] - 'A';
    112     if (u) {
    113       adj[u].push_back(i);
    114     }
    115   }
    116   For(i, 1, k) {
    117     scanf("%s", str + 1);
    118     int len = strlen(str + 1);
    119     std::reverse(str + 1, str + len + 1);
    120     ac.insert(len, i);
    121   }
    122   ac.build();
    123   DFS(1, 0);
    124   ac.DFS(0);
    125   For(i, 1, k) {
    126     printf("%d
    ", answer[i]);
    127   }
    128   return 0;
    129 }
    View Code

     H

    分成环和树两部分考虑,树上可以长链剖分统计,环上扫一遍即可,做到线性需要比较精细的实现。

    (实际上差分就行了,好写的多,我数据结构学傻了.jpg*2

      1 #include <bits/stdc++.h>
      2 
      3 #define IL __inline__ __attribute__((always_inline))
      4 
      5 #define For(i, a, b) for (int i = (a), i##end = (b); i <= i##end; ++ i)
      6 #define FOR(i, a, b) for (int i = (a), i##end = (b); i < i##end; ++ i)
      7 #define Rep(i, a, b) for (int i = (a), i##end = (b); i >= i##end; -- i)
      8 #define REP(i, a, b) for (int i = (a) - 1, i##end = (b); i >= i##end; -- i)
      9 
     10 typedef long long LL;
     11 
     12 template <class T>
     13 IL bool chkmax(T &a, const T &b) {
     14   return a < b ? ((a = b), 1) : 0;
     15 }
     16 
     17 template <class T>
     18 IL bool chkmin(T &a, const T &b) {
     19   return a > b ? ((a = b), 1) : 0;
     20 }
     21 
     22 template <class T>
     23 IL T mymax(const T &a, const T &b) {
     24   return a > b ? a : b;
     25 }
     26 
     27 template <class T>
     28 IL T mymin(const T &a, const T &b) {
     29   return a < b ? a : b;
     30 }
     31 
     32 template <class T>
     33 IL T myabs(const T &a) {
     34   return a > 0 ? a : -a;
     35 }
     36 
     37 const int INF = 0X3F3F3F3F;
     38 const double EPS = 1E-8, PI = acos(-1.0);
     39 
     40 #define DEBUG(...) fprintf(stderr, __VA_ARGS__)
     41 #define OK DEBUG("Passing [%s] in LINE %d...
    ", __FUNCTION__, __LINE__)
     42 
     43 const int MAXN = 500000 + 5;
     44 
     45 int to[MAXN], dep[MAXN], m_d[MAXN], son[MAXN], top[MAXN], pool[MAXN], size[MAXN], 
     46     *que[MAXN], pool_v[MAXN * 2], answer[MAXN], n, K, c_cnt, *cur = pool, *val = pool_v + MAXN;
     47 std::vector<int> adj[MAXN], cycle[MAXN];
     48 bool vis[MAXN], in_cycle[MAXN];
     49 
     50 void DFS1(int u) {
     51   static int stack[MAXN], top;
     52   static bool in_stack[MAXN];
     53   vis[u] = 1;
     54   stack[++ top] = u;
     55   in_stack[u] = 1;
     56   if (in_stack[to[u]]) {
     57     int cur = top;
     58     ++ c_cnt;
     59     do {
     60       cycle[c_cnt].push_back(stack[cur]);
     61       in_cycle[stack[cur]] = 1;
     62     } while (stack[cur --] != to[u]);
     63   } else if (!vis[to[u]]) {
     64     DFS1(to[u]);
     65   }
     66   in_stack[u] = 0;
     67   -- top;
     68 }
     69 
     70 void DFS2(int u) {
     71   for (auto &x : adj[u]) {
     72     if (!in_cycle[x]) {
     73       dep[x] = dep[u] + 1;
     74       DFS2(x);
     75       if (dep[m_d[x]] > dep[m_d[son[u]]]) {
     76         son[u] = x;
     77       }
     78     }
     79   }
     80   m_d[u] = son[u] ? m_d[son[u]] : u;
     81 }
     82 
     83 void DFS3(int u, int t) {
     84   if (u == t) {
     85     que[u] = cur;
     86     cur += size[u] = dep[m_d[u]] - dep[u];
     87     ++ cur;
     88   } else {
     89     que[u] = que[t];
     90   }
     91   top[u] = t;
     92   if (son[u]) {
     93     DFS3(son[u], t);
     94   }
     95   for (auto &x : adj[u]) {
     96     if (!in_cycle[x] && x != son[u]) {
     97       DFS3(x, x);
     98     }
     99   }
    100 }
    101 
    102 int DFS4(int u) {
    103   int cur = son[u] ? DFS4(son[u]) : 0, delta = dep[u] - dep[top[u]];
    104   ++ que[u][delta], ++ cur;
    105   if (delta + K < size[top[u]]) {
    106     cur -= que[u][delta + K + 1];
    107   }
    108   for (auto &x : adj[u]) {
    109     if (!in_cycle[x] && x != son[u]) {
    110       DFS4(x);
    111       For(i, 0, size[x]) {
    112         que[u][i + delta + 1] += que[x][i];
    113         assert(i + delta + 1 <= size[top[u]]);
    114         if (i < K) {
    115           cur += que[x][i];
    116         }
    117       }
    118     }
    119   }
    120   return answer[u] = cur;
    121 }
    122 
    123 int main() {
    124   scanf("%d%d", &n, &K);
    125   For(i, 1, n) {
    126     scanf("%d", &to[i]);
    127     adj[to[i]].push_back(i);
    128   }
    129   For(i, 1, n) {
    130     if (adj[i].empty()) {
    131       DFS1(i);
    132     }
    133   }
    134   For(i, 1, n) {
    135     if (!vis[i]) {
    136       DFS1(i);
    137     }
    138   }
    139   For(i, 1, c_cnt) {
    140     std::reverse(cycle[i].begin(), cycle[i].end());
    141     for (auto &x : cycle[i]) {
    142       DFS2(x);
    143       DFS3(x, x);
    144       DFS4(x);
    145     }
    146     int max = -INF, min = INF;
    147     REP(j, cycle[i].size(), 1) {
    148       int dist = (int)cycle[i].size() - j;
    149       For(k, 0, mymin(K, size[cycle[i][j]])) {
    150         val[dist + k] += que[cycle[i][j]][k];
    151         chkmax(max, dist + k);
    152         chkmin(min, dist + k);
    153       }
    154     }
    155     int sum = 0;
    156     For(j, 0, mymin(max, K)) {
    157       sum += val[j];
    158     }
    159     answer[cycle[i].front()] += sum;
    160     FOR(j, 1, cycle[i].size()) {
    161       sum -= val[K - j + 1];
    162       int dist = (int)cycle[i].size() - j;
    163       For(k, 0, mymin(K, size[cycle[i][j]])) {
    164         val[dist + k] -= que[cycle[i][j]][k];
    165         chkmax(max, dist + k);
    166         chkmin(min, dist + k);
    167         if (dist + k <= K - j) {
    168           sum -= que[cycle[i][j]][k];
    169         }
    170       }
    171       For(k, 0, mymin(K, size[cycle[i][j - 1]])) {
    172         val[k - j + 1] += que[cycle[i][j - 1]][k];
    173         chkmax(max, k - j + 1);
    174         chkmin(min, k - j + 1);
    175         if (k - j + 1 <= K - j) {
    176           sum += que[cycle[i][j - 1]][k];
    177         }
    178       }
    179       answer[cycle[i][j]] += sum;
    180     }
    181     For(j, min, max) {
    182       val[j] = 0;
    183     }
    184   }
    185   For(i, 1, n) {
    186     printf("%d
    ", answer[i]);
    187   }
    188   return 0;
    189 }
    View Code
  • 相关阅读:
    VC++中对数据类型的限制limits.h文件内容
    阿里巴巴-2015秋招研发工程师附加题
    阿里巴巴-2015秋招研发工程师附加题
    如何成为一个牛逼的程序猿
    Windows7中Java64位环境变量配置:javac不是内部命令或外部命令,也不是可运行的程序或批处理文件。
    程序员面试宝典:求十进制数字的二进制数位中包含1的个数
    程序员面试宝典:与或数值运算
    docker配置阿里云镜像
    原生JS中获取位置的方案总结
    vue项目中上拉加载和下拉刷新页面的实现
  • 原文地址:https://www.cnblogs.com/sjkmost/p/10826547.html
Copyright © 2020-2023  润新知