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...\n", __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)\text{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...\n", __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\n", 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...\n", __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('\n');
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('\n');
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...\n", __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\n", 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...\n", __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\n", answer.size());
222   for (auto &x : answer) {
223     printf("%d %d\n", x.first, x.second);
224   }
225   return 0;
226 }
View Code

 F

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

然后问题变成了这样:

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

有$n$次操作,每次操作给定区间$[l,r]$,然后对于$i\in[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...\n", __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\n", 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...\n", __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\n", 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...\n", __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\n", answer[i]);
187   }
188   return 0;
189 }
View Code

 

posted @ 2019-05-07 16:52  sjkmost  阅读(317)  评论(0编辑  收藏  举报