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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }